text:
from distutils.version import LooseVersion

from collections import OrderedDict
import copy
import json
import warnings

import tlz as toolz

import numpy as np
import pandas as pd

try:
    import fastparquet
    from fastparquet import ParquetFile
    from fastparquet.util import get_file_scheme
    from fastparquet.util import ex_from_sep, val_to_num, groupby_types
    from fastparquet.writer import partition_on_columns, make_part_file
except ImportError:
    pass

from .utils import _parse_pandas_metadata, _normalize_index_columns, _analyze_paths
from ..utils import _meta_from_dtypes
from ...utils import UNKNOWN_CATEGORIES

#########################
# Fastparquet interface #
#########################
from .utils import Engine

def _paths_to_cats(paths, file_scheme):
    """
    Extract categorical fields and labels from hive- or drill-style paths.
    FixMe: This has been pasted from https://github.com/dask/fastparquet/pull/471
    Use fastparquet.api.paths_to_cats from fastparquet>0.3.2 instead.

    Parameters
    ----------
    paths (Iterable[str]): file paths relative to root
    file_scheme (str):

    Returns
    -------
    cats (OrderedDict[str, List[Any]]): a dict of field names and their values
    """
    if file_scheme in ["simple", "flat", "other"]:
        cats = {}
        return cats

    cats = OrderedDict()
    raw_cats = OrderedDict()
    s = ex_from_sep("/")
    paths = toolz.unique(paths)
    if file_scheme == "hive":
        partitions = toolz.unique((k, v) for path in paths for k, v in s.findall(path))
        for key, val in partitions:
            cats.setdefault(key, set()).add(val_to_num(val))
            raw_cats.setdefault(key, set()).add(val)
    else:
        i_val = toolz.unique(
            (i, val) for path in paths for i, val in enumerate(path.split("/")[:-1])
        )
        for i, val in i_val:
            key = "dir%i" % i
            cats.setdefault(key, set()).add(val_to_num(val))
            raw_cats.setdefault(key, set()).add(val)

    for key, v in cats.items():
        # Check that no partition names map to the same value after transformation by val_to_num
        raw = raw_cats[key]
        if len(v) != len(raw):
            conflicts_by_value = OrderedDict()
            for raw_val in raw_cats[key]:
                conflicts_by_value.setdefault(val_to_num(raw_val), set()).add(raw_val)
            conflicts = [
                c for k in conflicts_by_value.values() if len(k) > 1 for c in k
            ]
            raise ValueError("Partition names map to the same value: %s" % conflicts)
        vals_by_type = groupby_types(v)

        # Check that all partition names map to the same type after transformation by val_to_num
        if len(vals_by_type) > 1:
            examples = [x[0] for x in vals_by_type.values()]
            warnings.warn(
                "Partition names coerce to values of different types, e.g. %s"
                % examples
            )

    cats = OrderedDict([(key, list(v)) for key, v in cats.items()])
    return cats

paths_to_cats = (
    _paths_to_cats  # FixMe: use fastparquet.api.paths_to_cats for fastparquet>0.3.2
)

def _determine_pf_parts(fs, paths, gather_statistics, **kwargs):
    """ Determine how to access metadata and break read into ``parts``

    This logic is mostly to handle `gather_statistics=False` cases,
    because this also means we should avoid scanning every file in the
    dataset.  If _metadata is available, set `gather_statistics=True`
    (if `gather_statistics=None`).

    The `fast_metadata` output specifies that ParquetFile metadata parsing
    is fast enough for each worker to perform during `read_partition`. The
    value will be set to True if: (1) The path is a directory containing
    _metadta, (2) the path is a list of files containing _metadata, (3)
    there is only one file to read, or (4) `gather_statistics` is False.
    In other cases, the ParquetFile object will need to be stored in the
    task graph, because metadata parsing is too expensive.
    """
    parts = []
    fast_metadata = True
    if len(paths) > 1:
        base, fns = _analyze_paths(paths, fs)
        if gather_statistics is not False:
            # This scans all the files, allowing index/divisions
            # and filtering
            if "_metadata" not in fns:
                paths_use = paths
                fast_metadata = False
            else:
                paths_use = base + fs.sep + "_metadata"
            pf = ParquetFile(
                paths_use, open_with=fs.open, sep=fs.sep, **kwargs.get("file", {})
            )
        else:
            if "_metadata" in fns:
                # We have a _metadata file, lets use it
                pf = ParquetFile(
                    base + fs.sep + "_metadata",
                    open_with=fs.open,
                    sep=fs.sep,
                    **kwargs.get("file", {})
                )
            else:
                # Rely on metadata for 0th file.
                # Will need to pass a list of paths to read_partition
                scheme = get_file_scheme(fns)
                pf = ParquetFile(paths[0], open_with=fs.open, **kwargs.get("file", {}))
                pf.file_scheme = scheme
                pf.cats = paths_to_cats(fns, scheme)
                parts = paths.copy()
    elif fs.isdir(paths[0]):
        # This is a directory, check for _metadata, then _common_metadata
        paths = fs.glob(paths[0] + fs.sep + "*")
        base, fns = _analyze_paths(paths, fs)
        if "_metadata" in fns:
            # Using _metadata file (best-case scenario)
            pf = ParquetFile(
                base + fs.sep + "_metadata",
                open_with=fs.open,
                sep=fs.sep,
                **kwargs.get("file", {})
            )
            if gather_statistics is None:
                gather_statistics = True

        elif gather_statistics is not False:
            # Scan every file
            pf = ParquetFile(paths, open_with=fs.open, **kwargs.get("file", {}))
            fast_metadata = False
        else:
            # Use _common_metadata file if it is available.
            # Otherwise, just use 0th file
            if "_common_metadata" in fns:
                pf = ParquetFile(
                    base + fs.sep + "_common_metadata",
                    open_with=fs.open,
                    **kwargs.get("file", {})
                )
            else:
                pf = ParquetFile(paths[0], open_with=fs.open, **kwargs.get("file", {}))
            scheme = get_file_scheme(fns)
            pf.file_scheme = scheme
            pf.cats = paths_to_cats(fns, scheme)
            parts = paths.copy()
    else:
        # There is only one file to read
        base = None
        pf = ParquetFile(
            paths[0], open_with=fs.open, sep=fs.sep, **kwargs.get("file", {})
        )

    return parts, pf, gather_statistics, fast_metadata, base

class FastParquetEngine(Engine):
    @classmethod
    def read_metadata(
        cls,
        fs,
        paths,
        categories=None,
        index=None,
        gather_statistics=None,
        filters=None,
        **kwargs
    ):
        # Define the parquet-file (pf) object to use for metadata,
        # Also, initialize `parts`.  If `parts` is populated here,
        # then each part will correspond to a file.  Otherwise, each part will
        # correspond to a row group (populated below).
        parts, pf, gather_statistics, fast_metadata, base_path = _determine_pf_parts(
            fs, paths, gather_statistics, **kwargs
        )

        columns = None
        if pf.fmd.key_value_metadata:
            pandas_md = [
                x.value for x in pf.fmd.key_value_metadata if x.key == "pandas"
            ]
        else:
            pandas_md = []

        if len(pandas_md) == 0:
            index_names = []
            column_names = pf.columns + list(pf.cats)
            storage_name_mapping = {k: k for k in column_names}
            column_index_names = [None]

        elif len(pandas_md) == 1:
            (
                index_names,
                column_names,
                storage_name_mapping,
                column_index_names,
            ) = _parse_pandas_metadata(json.loads(pandas_md[0]))
            #  auto-ranges should not be created by fastparquet
            index_names = [n for n in index_names if n is not None]
            column_names.extend(pf.cats)

        else:
            raise ValueError("File has multiple entries for 'pandas' metadata")

        if index is None and len(index_names) > 0:
            if len(index_names) == 1:
                index = index_names[0]
            else:
                index = index_names

        # Normalize user inputs
        column_names, index_names = _normalize_index_columns(
            columns, column_names, index, index_names
        )

        all_columns = index_names + column_names

        categories_dict = None
        if isinstance(categories, dict):
            categories_dict = categories

        if categories is None:
            categories = pf.categories
        elif isinstance(categories, str):
            categories = [categories]
        else:
            categories = list(categories)

        # Check that categories are included in columns
        if categories and not set(categories).intersection(all_columns):
            raise ValueError(
                "categories not in available columns.\n"
                "categories: {} | columns: {}".format(categories, list(all_columns))
            )

        dtypes = pf._dtypes(categories)
        dtypes = {storage_name_mapping.get(k, k): v for k, v in dtypes.items()}

        index_cols = index or ()
        meta = _meta_from_dtypes(all_columns, dtypes, index_cols, column_index_names)

        # fastparquet doesn't handle multiindex
        if len(index_names) > 1:
            raise ValueError("Cannot read DataFrame with MultiIndex.")

        for cat in categories:
            if cat in meta:
                meta[cat] = pd.Series(
                    pd.Categorical([], categories=[UNKNOWN_CATEGORIES]),
                    index=meta.index,
                )

        for catcol in pf.cats:
            if catcol in meta.columns:
                meta[catcol] = meta[catcol].cat.set_categories(pf.cats[catcol])
            elif meta.index.name == catcol:
                meta.index = meta.index.set_categories(pf.cats[catcol])
        if gather_statistics and pf.row_groups:
            stats = []
            if filters is None:
                filters = []

            skip_cols = set()  # Columns with min/max = None detected
            # make statistics conform in layout
            for (i, row_group) in enumerate(pf.row_groups):
                s = {"num-rows": row_group.num_rows, "columns": []}
                for i_col, col in enumerate(pf.columns):
                    if col not in skip_cols:
                        d = {"name": col}
                        cs_min = None
                        cs_max = None
                        if pf.statistics["min"][col][0] is not None:
                            cs_min = pf.statistics["min"][col][i]
                            cs_max = pf.statistics["max"][col][i]
                        elif (
                            dtypes[col] == "object"
                            and row_group.columns[i_col].meta_data.statistics
                        ):
                            cs_min = row_group.columns[
                                i_col
                            ].meta_data.statistics.min_value
                            cs_max = row_group.columns[
                                i_col
                            ].meta_data.statistics.max_value
                            if isinstance(cs_min, (bytes, bytearray)):
                                cs_min = cs_min.decode("utf-8")
                                cs_max = cs_max.decode("utf-8")
                        if None in [cs_min, cs_max] and i == 0:
                            skip_cols.add(col)
                            continue
                        if isinstance(cs_min, np.datetime64):
                            cs_min = pd.Timestamp(cs_min)
                            cs_max = pd.Timestamp(cs_max)
                        d.update(
                            {
                                "min": cs_min,
                                "max": cs_max,
                                "null_count": pf.statistics["null_count"][col][i],
                            }
                        )
                        s["columns"].append(d)
                # Need this to filter out partitioned-on categorical columns
                s["filter"] = fastparquet.api.filter_out_cats(row_group, filters)
                s["total_byte_size"] = row_group.total_byte_size
                s["file_path_0"] = row_group.columns[0].file_path  # 0th column only
                stats.append(s)

        else:
            stats = None

        pf._dtypes = lambda *args: pf.dtypes  # ugly patch, could be fixed
        pf.fmd.row_groups = None

        # Constructing "piece" and "pf" for each dask partition. We will
        # need to consider the following output scenarios:
        #
        #  1) Each "piece" is a file path, and "pf" is `None`
        #      - `gather_statistics==False` and no "_metadata" available
        #  2) Each "piece" is a row-group index, and "pf" is ParquetFile object
        #      - We have parquet partitions and no "_metadata" available
        #  3) Each "piece" is a row-group index, and "pf" is a `tuple`
        #      - The value of the 0th tuple element depends on the following:
        #      A) Dataset is partitioned and "_metadata" exists
        #          - 0th tuple element will be the path to "_metadata"
        #      B) Dataset is not partitioned
        #          - 0th tuple element will be the path to the data
        #      C) Dataset is partitioned and "_metadata" does not exist
        #          - 0th tuple element will be the original `paths` argument
        #            (We will let the workers use `_determine_pf_parts`)

        # Create `parts`
        # This is a list of row-group-descriptor dicts, or file-paths
        # if we have a list of files and gather_statistics=False
        base_path = (base_path or "") + fs.sep
        if parts:
            # Case (1)
            # `parts` is just a list of path names.
            pqpartitions = None
            pf_deps = None
            partsin = parts
        else:
            # Populate `partsin` with dataset row-groups
            partsin = pf.row_groups
            pqpartitions = pf.info.get("partitions", None)
            if pqpartitions and not fast_metadata:
                # Case (2)
                # We have parquet partitions, and do not have
                # a "_metadata" file for the worker to read.
                # Therefore, we need to pass the pf object in
                # the task graph
                pf_deps = pf
            else:
                # Case (3)
                # We don't need to pass a pf object in the task graph.
                # Instead, we can try to pass the path for each part.
                pf_deps = "tuple"

        parts = []
        i_path = 0
        path_last = None

        # Loop over DataFrame partitions.
        # Each `part` will be a row-group or path ()
        for i, part in enumerate(partsin):
            if pqpartitions and fast_metadata:
                # Case (3A)
                # We can pass a "_metadata" path
                file_path = base_path + "_metadata"
                i_path = i
            elif (
                pf_deps
                and isinstance(part.columns[0].file_path, str)
                and not pqpartitions
            ):
                # Case (3B)
                # We can pass a specific file/part path
                path_curr = part.columns[0].file_path
                if path_last and path_curr == path_last:
                    i_path += 1
                else:
                    i_path = 0
                    path_last = path_curr
                file_path = base_path + path_curr
            else:
                # Case (3C)
                # We cannot pass a specific file/part path
                file_path = paths
                i_path = i

            # Strip down pf object
            if pf_deps and pf_deps != "tuple":
                # Case (2)
                for col in part.columns:
                    col.meta_data.statistics = None
                    col.meta_data.encoding_stats = None

            # Final definition of "piece" and "pf" for this output partition
            piece = i_path if pf_deps else part
            pf_piece = (file_path, gather_statistics) if pf_deps == "tuple" else pf_deps
            part_item = {
                "piece": piece,
                "kwargs": {"pf": pf_piece, "categories": categories_dict or categories},
            }
            parts.append(part_item)

        return (meta, stats, parts)

    @classmethod
    def read_partition(
        cls, fs, piece, columns, index, categories=(), pf=None, **kwargs
    ):
        if isinstance(index, list):
            columns += index

        if pf is None:
            base, fns = _analyze_paths([piece], fs)
            scheme = get_file_scheme(fns)
            pf = ParquetFile(piece, open_with=fs.open)
            relpath = piece.replace(base, "").lstrip("/")
            for rg in pf.row_groups:
                for ch in rg.columns:
                    ch.file_path = relpath
            pf.file_scheme = scheme
            pf.cats = paths_to_cats(fns, scheme)
            pf.fn = base
            return pf.to_pandas(columns, categories, index=index)
        else:
            if isinstance(pf, tuple):
                if isinstance(pf[0], list):
                    pf = _determine_pf_parts(fs, pf[0], pf[1], **kwargs)[1]
                else:
                    pf = ParquetFile(
                        pf[0], open_with=fs.open, sep=fs.sep, **kwargs.get("file", {})
                    )
                pf._dtypes = lambda *args: pf.dtypes  # ugly patch, could be fixed
                pf.fmd.row_groups = None
            rg_piece = pf.row_groups[piece]
            pf.fmd.key_value_metadata = None
            return pf.read_row_group_file(
                rg_piece, columns, categories, index=index, **kwargs.get("read", {})
            )

    @classmethod
    def initialize_write(
        cls,
        df,
        fs,
        path,
        append=False,
        partition_on=None,
        ignore_divisions=False,
        division_info=None,
        **kwargs
    ):
        if append and division_info is None:
            ignore_divisions = True
        fs.mkdirs(path, exist_ok=True)
        object_encoding = kwargs.pop("object_encoding", "utf8")
        index_cols = kwargs.pop("index_cols", [])
        if object_encoding == "infer" or (
            isinstance(object_encoding, dict) and "infer" in object_encoding.values()
        ):
            raise ValueError(
                '"infer" not allowed as object encoding, '
                "because this required data in memory."
            )

        if append:
            try:
                # to append to a dataset without _metadata, need to load
                # _common_metadata or any data file here
                pf = fastparquet.api.ParquetFile(path, open_with=fs.open, sep=fs.sep)
            except (IOError, ValueError):
                # append for create
                append = False
        if append:
            if pf.file_scheme not in ["hive", "empty", "flat"]:
                raise ValueError(
                    "Requested file scheme is hive, but existing file scheme is not."
                )
            elif (set(pf.columns) != set(df.columns) - set(partition_on)) or (
                set(partition_on) != set(pf.cats)
            ):
                raise ValueError(
                    "Appended columns not the same.\n"
                    "Previous: {} | New: {}".format(pf.columns, list(df.columns))
                )
            elif (pd.Series(pf.dtypes).loc[pf.columns] != df[pf.columns].dtypes).any():
                raise ValueError(
                    "Appended dtypes differ.\n{}".format(
                        set(pf.dtypes.items()) ^ set(df.dtypes.iteritems())
                    )
                )
            else:
                df = df[pf.columns + partition_on]

            fmd = pf.fmd
            i_offset = fastparquet.writer.find_max_part(fmd.row_groups)
            if not ignore_divisions:
                if not set(index_cols).intersection([division_info["name"]]):
                    ignore_divisions = True
            if not ignore_divisions:
                minmax = fastparquet.api.sorted_partitioned_columns(pf)
                old_end = minmax[index_cols[0]]["max"][-1]
                divisions = division_info["divisions"]
                if divisions[0] < old_end:
                    raise ValueError(
                        "Appended divisions overlapping with previous ones."
                        "\n"
                        "Previous: {} | New: {}".format(old_end, divisions[0])
                    )
        else:
            fmd = fastparquet.writer.make_metadata(
                df._meta,
                object_encoding=object_encoding,
                index_cols=index_cols,
                ignore_columns=partition_on,
                **kwargs
            )
            i_offset = 0

        return (fmd, i_offset)

    @classmethod
    def write_partition(
        cls,
        df,
        path,
        fs,
        filename,
        partition_on,
        return_metadata,
        fmd=None,
        compression=None,
        **kwargs
    ):
        fmd = copy.copy(fmd)
        if not len(df):
            # Write nothing for empty partitions
            rgs = []
        elif partition_on:
            mkdirs = lambda x: fs.mkdirs(x, exist_ok=True)
            if LooseVersion(fastparquet.__version__) >= "0.1.4":
                rgs = partition_on_columns(
                    df, partition_on, path, filename, fmd, compression, fs.open, mkdirs
                )
            else:
                rgs = partition_on_columns(
                    df,
                    partition_on,
                    path,
                    filename,
                    fmd,
                    fs.sep,
                    compression,
                    fs.open,
                    mkdirs,
                )
        else:
            with fs.open(fs.sep.join([path, filename]), "wb") as fil:
                fmd.num_rows = len(df)
                rg = make_part_file(
                    fil, df, fmd.schema, compression=compression, fmd=fmd
                )
            for chunk in rg.columns:
                chunk.file_path = filename
            rgs = [rg]
        if return_metadata:
            return rgs
        else:
            return []

    @classmethod
    def write_metadata(cls, parts, fmd, fs, path, append=False, **kwargs):
        _meta = copy.copy(fmd)
        if parts:
            for rg in parts:
                if rg is not None:
                    if isinstance(rg, list):
                        for r in rg:
                            _meta.row_groups.append(r)
                    else:
                        _meta.row_groups.append(rg)
            fn = fs.sep.join([path, "_metadata"])
            fastparquet.writer.write_common_metadata(
                fn, _meta, open_with=fs.open, no_row_groups=False
            )

        # if appending, could skip this, but would need to check existence
        fn = fs.sep.join([path, "_common_metadata"])
        fastparquet.writer.write_common_metadata(fn, _meta, open_with=fs.open)

redpajama_set_name: RedPajamaGithub


text:
# Play Acl Module

*A lightweight and flexible ACL component*

[![Build Status](https://travis-ci.org/de-ceow/scala-acl.svg?branch=master)](https://travis-ci.org/Scyks/play-acl)

This is a module to implement a simple ACL system to any of your applications.
By using the play plugin you can protect controller actions, or anything else.

You can protect an admin area, or hide information / actions for specific users.
It's also possible to connect a right to specific conditions for objects.

Let's say you have a shop system and want to display orders. The orders are separated
in 2 lists (open orders and closed orders). For this case you can use the acl system
to filter entries between these 2 lists.

# Install

You can easily use the sbt tool to download the resources to your project.

```scala
libraryDependencies  ++=  Seq(
	"de.ceow" %% "scala-acl" % "1.2.0",
	"de.ceow" %% "play-acl" % "1.2.0" // for play 2.5
	"de.ceow" %% "play-acl" % "1.3.0" // for play 2.6
)
```

# How does the ACL system work

The Acl system is based on classic roles. A user can have one or more roles. Each role
have resources and privileges. A resource is a entity or an are / module to separate
rights. A privilege is the action the user want to do, like read, update, delete, expand,
manage, send, ... .

A User have roles, and will be initialized with the ACL system. An Anonymous user is also
a representation of a user, but with none or different roles.

Roles are objects, with a unique identifier which. The identifier is a bit value like
1, 2, 4, 8, 16 ...

## Define resources

A resource have to extend `de.ceow.security.acl.Resource` and contain a string identifier.

```scala
object AdminResource extends de.ceow.security.acl.Resource("admin")
```

## Define Privileges

A privilege have to extend `de.ceow.security.acl.Privilege` and contain a string identifier.

```scala
object ReadPrivilege extends de.ceow.security.acl.Privilege("read")
```

## Define Roles

A Role have to implement `de.ceow.security.acl.Role` interface, which contains 4 abstract methods:

* `getIdentifier: Long`: the role identifier bit value
* `getRoleId: String`: returns a string identifier of this role
* `getInheritedRole: List[Role]`: a list of parent roles
* `getPrivileges: Map[Resource, Map[Privilege, Seq[Assert]]]`: the complete definition of rights

### Assertions

Assertions are classes with an apply method. The parameters are`Option[AclObject]` and `Acl`.
You can check specific conditions on a resource. When you have a list of users, and want to show an edit button
to directly edit this user `u` can use this. An admin will have no restriction, an anonymous user
is denied for this operation, but a user can edit his own entry.

```scala
object myRole extends Role {
  override def getPrivileges: Map[Resource, Map[Privilege, Seq[Assert]]] = Map(
    Resource -> Map(
      Privilege -> Seq(Asserts.isMe)
    )
  }
}
val myId = 4
case class User(id: Int) extends AclObject
object Asserts {

  object IsMe extends Assert {
    // the assert definition
    def apply(obj: Option[AclObject], acl: Acl) => obj match {
      case Some(u: User) => u.exists(_.id == acl.observerEntity.id)
      case _ => false
    }
  }
}

acl.isAllowed(UserResource, EditPrivilege, Some(currentUser)) // returns true or false
```
# Play Framework

## The Security Trait

For Initialization of the Acl you need to configure the Security Trait. This Trait will be used
in a controller action to initialize and retrieve the ACL instance for the current user. When there
is no user logged in, there is a guest user defined. To implement the Security trait you need to
define these methods:

* `userByUsername(username: String)(implicit acl: Acl): Option[I]` to retrieve a user from some storage by given username
* `roles: List[Role]` the list of available roles
* `guestRole: Role` the guest role
* `guestUser: UserEntity` to return a guest / anonymous user

## Putting all Together

To configure your acl system you have to define "Resources", "Privileges", "Roles" and the "Security" trait.
I'll show a dummy implementation:

```scala
import de.ceow.security.acl.{Resource, Privilege, Role, Identity}
import de.ceow.security.acl.play.Security

/** Resources */
object MainResource extends Resource("main")
object UserResource extends Resource("user")
object AdminResource extends Resource("admin")

/** Privileges */
object ReadPrivilege extends Privilege("read")
object CreatePrivilege extends Privilege("create")
object LoggedInPrivilege extends Privilege("loggedIn")
object ManagePrivilege extends Privilege("manage")

/** User Roles */
object Guest extends Role {

	override def getIdentifier: Long = 1L
	override def getPrivileges: Map[Resource, Map[Privilege, Seq[Assert]]] = {
		Map(
			MainResource -> Map(
				ReadPrivilege -> Seq()
			),
			UserResource -> Map(
				ReadPrivilege -> Seq(),
				CreatePrivilege -> Seq()
			)
		)
	}
	override def getInheritedRoles: List[Role] = List()
	override def getRoleId: String = "guest"
}
object Registered extends Role {

	override def getIdentifier: Long = 2L
	override def getPrivileges: Map[Resource, Map[Privilege, Seq[Assert]]] = {
		Map(
			UserResource -> Map(
				LoggedInPrivilege -> Seq()
			)
		)
	}
	override def getInheritedRoles: List[Role] = List(Guest)
	override def getRoleId: String = "registered"
}

object Admin extends Role {

	override def getIdentifier: Long = 4L
	override def getPrivileges: Map[Resource, Map[Privilege, Seq[Assert]]] = {
		Map(
			AdminResource -> Map(
				ReadPrivilege -> Seq(),
				ManagePrivilege -> Seq()
			)
		)
	}
	override def getInheritedRoles: List[Role] = List(Registered)
	override def getRoleId: String = "admin"
}

case class UserEntity(id: Int, roles: Long) extends Identity

trait Security extends de.ceow.security.acl.play.AclSecurity[UserEntity] {
	def userByUsername(username: String)(implicit request: RequestHeader): Option[UserEntity] = {
		UserRepository.findByUserName(username) match {
			case Success(user) => Some(user)
			case Failure(ex) => None
		}
	}
	override def roles: List[Role] = Guest :: Registered :: Admin:: Nil
	override def guestRole: Role = Guest
	override def guestUser: UserEntity = new UserEntity(0, 1L)
	override def onUnauthenticated(request: RequestHeader) = Results.Redirect("/login")
	override def onUnauthorized(request: RequestHeader) = Results.Redirect("/login")
}
trait AsyncSecurity extends de.ceow.security.acl.play.AsyncSecurity[UserEntity] with Security {}
```

# Protecting Controller instances or get ACL instance

Because of being stateless, the controller is the entry point for the ACL system and
it will be initialized there. Also when you want to retrieve the logged in user.

The Standard implementation contains 4 Methods, which are checking if a user is logged in
and return the Acl or the user instance or even check a resource and privilege directly.

**Normal Security Trait**

* `withAuth`: check if user is logged in, otherwise `onUnauthenticated` will be called
* `withUser`: will provide the logged in or the guest user instance
* `withAcl`: will provide the acl instance
* `withProtected(r: Resource, p: Privilege)`:
    * if acl check against resource privilege fails -> `onUnauthorized` will be called
* `withProtected(r: Resource, p: Privilege, objectToCheck: () => Option[AclObject])`:
    * if acl check against resource privilege on objectToCheck fails -> `onUnauthorized` will be called
* `withProtected(r: Resource, p: Privilege, objectToCheck: Acl => Option[AclObject])`:
    * same as above except the Acl as an input parameter
* `withProtectedAcl(r: Resource, p: Privilege)`:
    * if acl check against resource privilege fails -> `onUnauthorized` will be called
    * if logged in and acl check is true -> return Acl Instance
* `withProtectedAcl(r: Resource, p: Privilege, objectToCheck: () => Option[AclObject])`:
    * if acl check against resource privilege on objectToCheck fails -> `onUnauthorized` will be called
    * if logged in and acl check is true -> return Acl Instance
* `withProtectedAcl(r: Resource, p: Privilege, objectToCheck: Acl => Option[AclObject])`:
    * same as above except the Acl as an input parameter

**Async Security Trait**

* `withAuthAsync`: check if user is logged in, otherwise `onUnauthenticated` will be called
* `withUserAsync`: will provide the logged in or the guest user instance
* `withAclAsync`: will provide the acl instance
* `withProtectedAsync(r: Resource, p: Privilege)`:
    * if acl check against resource privilege fails -> `onUnauthorized` will be called
* `withProtectedAsync(r: Resource, p: Privilege, objectToCheck: () => Option[AclObject])`:
    * if acl check against resource privilege on objectToCheck fails -> `onUnauthorized` will be called
* `withProtectedAsync(r: Resource, p: Privilege, objectToCheck: Acl => Option[AclObject])`:
    * same as above except the Acl as an input parameter
* `withProtectedAclAsync(r: Resource, p: Privilege)`:
    * if acl check against resource privilege fails -> `onUnauthorized` will be called
    * if logged in and acl check is true -> return Acl Instance
* `withProtectedAclAsync(r: Resource, p: Privilege, objectToCheck: () => Option[AclObject])`:
    * if acl check against resource privilege on objectToCheck fails -> `onUnauthorized` will be called
    * if logged in and acl check is true -> return Acl Instance
* `withProtectedAclAsync(r: Resource, p: Privilege, objectToCheck: Acl => Option[AclObject])`:
    * same as above except the Acl as an input parameter

# Implementation in controller

To protect a controller action or retrieve Acl or current user, see the following example:

```scala
package controllers

import <your security trait>
import <your resources and privileges>
import <your user entity>
import play.api.mvc.InjectedController
import de.ceow.security.acl.Acl

/** Admin controller - we want to protected this */
class Admin @Inject()(val messagesApi: MessagesApi, override val configuration: Configuration) extends InjectedController with Security {

	def dashboard = withAuth { implicit request =>
		Ok("")
	}

	def dashboard = withUser { implicit user: UserEntity => implicit request =>
		Ok("")
	}

	def dashboard = withAcl { implicit acl: Acl => implicit request =>
		Ok("")
	}

	def dashboard = withProtected(AdminResource, ReadPrivilege) { implicit request =>
    	Ok("")
	}

	def dashboard = withProtected(AdminResource, ReadPrivilege, DataSource.getData) { user => implicit request =>
    	Ok("")
	}

	def dashboard = withProtectedAcl(AdminResource, ReadPrivilege) { implicit acl: Acl => implicit request =>
    	Ok("")
	}

	def dashboard = withProtectedAcl(AdminResource, ReadPrivilege, DataSource.getData) { user => implicit acl: Acl => implicit request =>
    	Ok("")
	}
}
```

# Using acl protection in views / controller

A Requirement for doing this is an instance of `acl: Acl` in the current context. The acl object
will be passed as `implicit` parameter.

For checking the rights you have a lot of options to ask:

* `acl.isAllowed(Resource, Privilege, Some(AclObject))`

__use `AllowLike` trait__

To use this `AllowLike` trait, you need an AclObject.

`case class User extends AclObject With AllowLike`

* `acl allows Resource to Privilege`
* `acl allows Privilege at Resource`
* `acl allows AclObject ad Resource to Privilege`
* `AclObject allows Resource to Privilege`
* `AclObject allows Privilege at Resource`
* `Resource allows Privilege`
* `Resource allows AclObject to Privilege`
* `Privilege allows Resource`
* `Privilege allows AclObject at Resource`

## View implementation

In a view it's necessary to provide implicit acl instance.

__without request__

```scala
@import de.ceow.security.acl.Acl
@()(implicit acl: Acl)

@if(acl allows Resource to Privilege) {
	<h1>Hello World</h1>
}
```

__with request__

```scala
@import de.ceow.security.acl.Acl
@()(implicit request: RequestHeader, acl: Acl)

@if(acl allows Resource to Privilege) {
	<h1>Hello World</h1>
}
```
## Changelog

### 1.2.0
*scala-acl*
- add Scala version (2.11.11, 2.12.1, 2.12.2)
- simplify pattern matching

*play-acl*
- removed `new` for case class creation
- allow to provide acl object as an input for `objectToCheck`
  beside `withProtectedAcl(r: Resource, p: Privilege, objectToCheck: () => Option[AclObject])`
  also `withProtectedAcl(r: Resource, p: Privilege, objectToCheck: Acl => Option[AclObject])`

### 1.1.0

- Change Assert from function to abstract class

### 1.0.0

- separate acl and play-acl to different modules
- implement Privilege.deny rule
- change inheritance to use role inheritance only
- use Acl.Assert as type definition for assertions
- update play framework to 2.5.x

### 0.7.0

- implement async trait to use acl also in async actions

### 0.6.0

- implementing unit tests for Security Trait
- reuse code blocks in security trait
- pass checked object to controller action
- implement travis ci

### 0.5.0

- update scala version to 2.11.8
- update play framework to 2.5.0

### 0.4.0

- passing the acl instance to the assertion
- implement 2 new methods to check also in play controller against an AclObject


text:
<?php

namespace LQNL\ClienteBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use LQNL\ClienteBundle\Entity\Solicitacao;
use LQNL\ClienteBundle\Entity\Disponibilidade;
use LQNL\ClienteBundle\Form\SolicitacaoType;

/**
 * Solicitacao controller.
 *
 */
class SolicitacaoController extends Controller {

    /**
     * Lists all Solicitacao entities.
     *
     */
    public function indexAction() {
        $em = $this->getDoctrine()->getManager();
        $user = $this->getUser();
        $entities = $em->getRepository('ClienteBundle:Solicitacao')->findBy(array('usuario' => $user));
        return $this->render('ClienteBundle:Solicitacao:index.html.twig', array(
                    'usuario' => $user,
                    'entities' => $entities,
        ));
    }

    /**
     * Creates a new Solicitacao entity.
     *
     */
    public function createAction(Request $request) {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('ClienteBundle:Usuario')->find($this->getUser()->getId());
        $status = "Em Aberto";
        $dataabertura = new \DateTime;
        $disponibilidades = $this->validaDisponibilidade($user, $request);
        if ($disponibilidades) {
            $i = 0;
            $user = $em->getRepository('ClienteBundle:Usuario')->find($this->getUser()->getId());
            foreach ($disponibilidades as $disponibilidade) {
                $em->persist($disponibilidade);
                $em->flush();
                $i++;
            }

            $disp = $entity = $em->getRepository('ClienteBundle:Disponibilidade')->findBy(array('responsavel' => $user->getId()), array('id' => 'DESC'));

            $entity = new Solicitacao();
            $form = $this->createCreateForm($entity);
            $form->handleRequest($request);

            if ($entity->getEletronico() == 0)
                $entity->setEletronico(0);
            if ($entity->getMetal() == 0)
                $entity->setMetal(0);
            if ($entity->getOutros() == 0)
                $entity->setOutros(0);
            if ($entity->getPapel() == 0)
                $entity->setPapel(0);
            if ($entity->getPlastico() == 0)
                $entity->setPlastico(0);
            if ($entity->getVidro() == 0)
                $entity->setVidro(0);

            $entity->setUsuario($user);
            $entity->setStatus($status);
            $entity->setData($dataabertura);

            if ($i > 2) {
                $entity->setDisponibilidade3($disp[0]);
                $entity->setDisponibilidade2($disp[1]);
                $entity->setDisponibilidade1($disp[2]);
            } elseif ($i > 1) {
                $entity->setDisponibilidade2($disp[0]);
                $entity->setDisponibilidade1($disp[1]);
            } elseif ($i == 1) {
                $entity->setDisponibilidade1($disp[0]);
            }

            if ($form->isValid()) {
                $em->persist($entity);
                $em->flush();

                return $this->redirect($this->generateUrl('solicitacao'));
            }
        }
        $entity = new Solicitacao();
        $form = $this->createCreateForm($entity);
        $form->handleRequest($request);

        return $this->render('ClienteBundle:Solicitacao:new.html.twig', array(
                    'usuario' => $this->getUser(),
                    'entity' => $entity,
                    'form' => $form->createView(),
                    'erroDisp' => 'A data da disponibilidade deve ser a partir do próximo dia útil.'
        ));
    }

    /**
     * Creates a form to create a Solicitacao entity.
     *
     * @param Solicitacao $entity The entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createCreateForm(Solicitacao $entity) {
        $form = $this->createForm(new SolicitacaoType(), $entity, array(
            'action' => $this->generateUrl('solicitacao_create'),
            'method' => 'POST',
        ));

        $form->add('submit', 'submit', array('label' => 'Create'));

        return $form;
    }

    /**
     * Displays a form to create a new Solicitacao entity.
     *
     */
    public function newAction() {
        $entity = new Solicitacao();
        $form = $this->createCreateForm($entity);
        $usuario = $this->getUser();
        return $this->render('ClienteBundle:Solicitacao:new.html.twig', array(
                    'entity' => $entity,
                    'form' => $form->createView(),
                    'usuario' => $usuario,
        ));
    }

    /**
     * Finds and displays a Solicitacao entity.
     *
     */
    public function showAction($id) {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ClienteBundle:Solicitacao')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Solicitacao entity.');
        }

        $deleteForm = $this->createDeleteForm($id);

        return $this->render('ClienteBundle:Solicitacao:show.html.twig', array(
                    'entity' => $entity,
                    'delete_form' => $deleteForm->createView(),
                    'usuario' => $this->getUser()
        ));
    }

    /**
     * Displays a form to edit an existing Solicitacao entity.
     *
     */
    public function editAction($id) {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ClienteBundle:Solicitacao')->find($id);
        //$disponibilidade3 = $em->getRepository('ClienteBundle:Disponibilidade')->find($entity->getDisponibilidade3()->getId());
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Solicitacao entity.');
        }

        $editForm = $this->createEditForm($entity);
        $deleteForm = $this->createDeleteForm($id);

        return $this->render('ClienteBundle:Solicitacao:edit.html.twig', array(
                    'usuario' => $this->getUser(),
                    'entity' => $entity,
                    'edit_form' => $editForm->createView(),
                    'delete_form' => $deleteForm->createView(),
//                    'disponibilidade1' => $disponibilidade1,
//                    'disponibilidade2' => $disponibilidade2,
                        //        'disponibilidade3' => $disponibilidade3,
        ));
    }

    /**
     * Creates a form to edit a Solicitacao entity.
     *
     * @param Solicitacao $entity The entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createEditForm(Solicitacao $entity) {
        $form = $this->createForm(new SolicitacaoType(), $entity, array(
            'action' => $this->generateUrl('solicitacao_update', array('id' => $entity->getId())),
            'method' => 'PUT',
        ));

        $form->add('submit', 'submit', array('label'
            => 'Update'));

        return $form;
    }

    /**
     * Edits an existing Solicitacao entity.
     *
     */
    public function updateAction(Request $request, $id) {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('ClienteBundle:Usuario')->find($this->getUser()->getId());
        $entity = $em->getRepository('ClienteBundle:Solicitacao')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Solicitacao entity.');
        }
        $disponibilidades = $this->validaDisponibilidade($user, $request);
        if ($disponibilidades) {
            $i = 0;
            foreach ($disponibilidades as $disponibilidade) {
                switch ($i) {
                    case 0:
                        $dispAux1 = $em->getRepository('ClienteBundle:Disponibilidade')->find($entity->getDisponibilidade1()->getId());
                        $dispAux1->setDia($disponibilidade->getDia());
                        $dispAux1->setTurno($disponibilidade->getTurno());
                        break;
                    case 1:
                        $dispAux2 = $em->getRepository('ClienteBundle:Disponibilidade')->find($entity->getDisponibilidade2()->getId());
                        $dispAux2->setDia($disponibilidade->getDia());
                        $dispAux2->setTurno($disponibilidade->getTurno());
                        break;
                    case 2:
                        $dispAux3 = $em->getRepository('ClienteBundle:Disponibilidade')->find($entity->getDisponibilidade3()->getId());
                        $dispAux3->setDia($disponibilidade->getDia());
                        $dispAux3->setTurno($disponibilidade->getTurno());
                        break;
                }
                $i++;
            }
            $editForm = $this->createEditForm($entity);
            $editForm->handleRequest($request);

            if ($entity->getEletronico() == 0)
                $entity->setEletronico(0);
            if ($entity->getMetal() == 0)
                $entity->setMetal(0);
            if ($entity->getOutros() == 0)
                $entity->setOutros(0);
            if ($entity->getPapel() == 0)
                $entity->setPapel(0);
            if ($entity->getPlastico() == 0)
                $entity->setPlastico(0);
            if ($entity->getVidro() == 0)
                $entity->setVidro(0);

            if ($editForm->isValid()) {
                $em->flush();

                return $this->redirect($this->generateUrl('solicitacao_show', array('id' => $id)));
            }

            return $this->render('ClienteBundle:Solicitacao:edit.html.twig', array(
                        'entity' => $entity,
                        'edit_form' => $editForm->createView(),
            ));
        }
    }

    /**
     * Cancelar a Solicitacao entity.
     *
     */
    public function cancelarAction($id) {
        $em = $this->getDoctrine()->getManager();
        $entity = $em->getRepository('ClienteBundle:Solicitacao')->find($id);
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Solicitacao entity.');
        }

        $entity->setStatus("Cancelada");
        $em->flush();

        return $this->redirect($this->generateUrl('solicitacao'));
    }

    /**
     * Deletes a Solicitacao entity.
     *
     */
    public function deleteAction(Request $request, $id) {
        $form = $this->createDeleteForm($id);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $entity = $em->getRepository('ClienteBundle:Solicitacao')->find($id);

            if (!$entity) {
                throw $this->createNotFoundException('Unable to find Solicitacao entity.');
            }

            $em->remove($entity);
            $em->flush();
        }

        return $this->redirect($this->generateUrl('solicitacao'));
    }

    /**
     * Creates a form to delete a Solicitacao entity by id.
     *
     * @param mixed $id The entity id
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm($id) {
        return $this->createFormBuilder()
                        ->setAction($this->generateUrl('solicitacao_delete', array('id' => $id)))
                        ->setMethod('DELETE')
                        ->add('submit', 'submit', array('label' => 'Delete'))
                        ->getForm()
        ;
    }

//
//    public function showAction($id) {
//        $em = $this->getDoctrine()->getManager();
//
//        $solicitacao = $em->getRepository('ClienteBundle:Solicitacao')->find($id);
//
//        if (!$solicitacao) {
//            return null;
//        }
//
//        return $solicitacao;
//    }

    function validateDate($date, $format = 'Y-m-d H:i:s') {

        $d = \DateTime::createFromFormat($format, $date);
        return $d && $d->format($format) == $date;
    }

    function validaDisponibilidade($user, $request) {
        $disp1 = $request->get('disp1');
        $disp2 = $request->get('disp2');
        $disp3 = $request->get('disp3');
        $disponibilidade1 = new Disponibilidade ();
        $disponibilidade2 = new Disponibilidade();
        $disponibilidade3 = new Disponibilidade();
        if ($this->validateDate($disp1, "d/m/Y")) {
            if ($this->validateDate($disp2, "d/m/Y")) {
                if ($this->validateDate($disp3, "d/m/Y")) {
                    $data1 = \DateTime::createFromFormat("d/m/Y", $disp1);
                    $data2 = \DateTime::createFromFormat("d/m/Y", $disp2);
                    $data3 = \DateTime::createFromFormat("d/m/Y", $disp3);
                    $disponibilidade1->setDia($data1);
                    $disponibilidade1->setTurno($request->get('turno1'));
                    $disponibilidade1->setResponsavel($user);
                    $disponibilidade2->setDia($data2);
                    $disponibilidade2->setTurno($request->get('turno2'));
                    $disponibilidade2->setResponsavel($user);
                    $disponibilidade3->setDia($data3);
                    $disponibilidade3->setTurno($request->get('turno3'));
                    $disponibilidade3->setResponsavel($user);
                    return array($disponibilidade1, $disponibilidade2, $disponibilidade3);
                } else {
                    $data1 = \DateTime::createFromFormat("d/m/Y", $disp1);
                    $data2 = \DateTime::createFromFormat("d/m/Y", $disp2);
                    $disponibilidade1->setDia($data1);
                    $disponibilidade1->setTurno($request->get('turno1'));
                    $disponibilidade1->setResponsavel($user);
                    $disponibilidade2->setDia($data2);
                    $disponibilidade2->setTurno($request->get('turno2'));
                    $disponibilidade2->setResponsavel($user);
                    return array($disponibilidade1, $disponibilidade2);
                }
            } elseif ($this->validateDate($disp3, "d/m/Y")) {
                $data1 = \DateTime::createFromFormat("d/m/Y", $disp1);
                $data3 = \DateTime::createFromFormat("d/m/Y", $disp3);
                $disponibilidade1->setDia($data1);
                $disponibilidade1->setTurno($request->get('turno1'));
                $disponibilidade1->setResponsavel($user);
                $disponibilidade3->setDia($data3);
                $disponibilidade3->setTurno($request->get('turno3'));
                $disponibilidade3->setResponsavel($user);

                return array($disponibilidade1, $disponibilidade3);
            }
            $data1 = \DateTime::createFromFormat("d/m/Y", $disp1);
            $disponibilidade1->setDia($data1);
            $disponibilidade1->setTurno($request->get('turno1'));
            $disponibilidade1->setResponsavel($user);
            return array($disponibilidade1);
        }
        return false;
    }

}


text:
import * as fs from "fs";
import * as path from "path";
import * as chai from "chai";
import {concat} from "../src/index";
import {Options} from "../src/options";

import expect = chai.expect;

var testCasesDir = "build/tests/cases/";
var referenceBaselineDir = "tests/baselines/reference/";
var localBaselineDir = "tests/baselines/local/";

function setupCases(): void {

    processDir(testCasesDir, "json", setupCase);
}

function processDir(path: string, ext: string, cb: (filename: string) => void): void {

    var files = fs.readdirSync(path);
    var filter = new RegExp("\." + ext + "$");

    for (var i = 0, l = files.length; i < l; i++) {

        var filename = files[i];
        if(filter.test(filename)) {
            cb(files[i]);
        }
    }
}

function setupCase(filename: string): void {

    var baseName = path.basename(filename, ".json");
    var options: Options = loadOptions(testCasesDir + filename);

    var name = 'Case ' + filename,
        description = (<any>options).description;

    if(description) {
        name += ": " + description;
    }

    describe(name, () => {

        var errorsFilename = baseName + ".errors.txt";
        var declarationFilename = baseName + ".d.ts";

        before((done) => {

            deleteFile(localBaselineDir + errorsFilename);
            deleteFile(localBaselineDir + declarationFilename);

            options.outDir = localBaselineDir;
            options.main = testCasesDir + "/" + options.main;

            concat(options, (err) => {
                if(err) {
                    fs.writeFileSync(localBaselineDir + errorsFilename , err.toString(), "utf8");
                }

                done();
            });
        });

        it('should have correct errors in ' + errorsFilename, () => {

            compareToBaseline(errorsFilename);
        });

        it('should have correct declarations in ' + declarationFilename, () => {

            compareToBaseline(declarationFilename);
        });

        after(() => {
            errorsFilename = undefined;
            declarationFilename = undefined;
        });
    });
}

function loadOptions(filename: string): Options {

    return JSON.parse(fs.readFileSync(filename, "utf8"));
}

function deleteFile(filePath: string): void {

    if(fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
    }
}

function compareToBaseline(filename: string): void {

    var localFilename = localBaselineDir + filename;
    var referenceFilename = referenceBaselineDir + filename;

    var localExists = fs.existsSync(localFilename);
    var referenceExists = fs.existsSync(referenceFilename);

    if(localExists && !referenceExists) {
        throw new Error("Unexpected file " + filename);
    }

    if(referenceExists && !localExists) {
        throw new Error("Missing file " + filename);
    }

    expect(readFile(localBaselineDir + filename), "Baseline changed for " + filename)
        .to.deep.equal(readFile(referenceBaselineDir + filename));
}

function readFile(filePath: string): any {

    var isJsonFile = path.extname(filePath) == ".json";

    if(!fs.existsSync(filePath)) {
        return isJsonFile ? {} : "";
    }

    var text = fs.readFileSync(filePath, "utf8");
    return isJsonFile ? JSON.parse(text) : text;
}

setupCases();


text:
class AppState;
class Game;
enum EDodgerAppState;

#define DEFAULT_BACKGROUND "data/space_bg.jpg"
#define MAIN_MENU_BACKGROUND "data/main_menu_bg.jpg"
#define MENU_DELAY 0.2
#define LANG_EN_FILENAME "data/text_en.txt"
#define LANG_ES_FILENAME "data/text_es.txt"
#define LEVEL_1_FILENAME "data/level1.txt"
#define LEVEL_2_FILENAME "data/level2.txt"
#define LEVEL_3_FILENAME "data/level3.txt"

enum EDodgerColor {
	EDG_CLR_BLUE,
	EDG_CLR_GREEN,
	EDG_CLR_RED,
	EDG_CLR_WHITE,
	EDG_CLR_YELLOW,
	EDG_CLR_NUM_COLORS
};

enum EDodgerMenuOp {
	EDMO_EXIT_APP,
	EDMO_GAME_OVER,
	EDMO_LANG_ES,
	EDMO_LANG_EN,
	EDMO_LEVEL_1,
	EDMO_LEVEL_2,
	EDMO_LEVEL_3,
	EDMO_START_MENU,
	EDMO_NUM_OPTIONS
};
enum EDodgerEntityType {
	EDET_PLAYER,
	EDET_ADD_SPEED,
	EDET_ENEMY,
	EDET_POINTS,
	EDET_SUB_SPEED,
	EDET_NUM_TYPES
};

extern AppState * g_currentAppState;
extern EDodgerAppState g_wantedState;
extern Game * g_game;

extern EDodgerMenuOp g_currentMenuOp;

extern void GSetWantedState(EDodgerAppState newState);

#endif //!_DEFS_H


text:
<?php
/**
 * Created by PhpStorm.
 * User: hebidu
 * Date: 2017-08-11
 * Time: 13:46
 */

namespace sunsun\hwfish\dal;

use sunsun\server\consts\DeviceType;
use sunsun\server\db\DbPool;
use sunsun\server\interfaces\BaseDalV2;

class HwfishBaseDal extends BaseDalV2
{
    public function __construct($db = null)
    {
        if($db == null){
            $db = DbPool::getInstance()->getDbByType(DeviceType::Did_Hwfish);
        }
        parent::__construct($db);
    }
}


text:
import {
    cast,
    Diagnostics,
    factory,
    getTokenAtPosition,
    isCallExpression,
    Node,
    SourceFile,
    textChanges,
    TextSpan,
    textSpanEnd,
} from "../_namespaces/ts";
import {
    codeFixAll,
    createCodeFixAction,
    registerCodeFix,
} from "../_namespaces/ts.codefix";

const fixId = "addMissingNewOperator";
const errorCodes = [Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code];
registerCodeFix({
    errorCodes,
    getCodeActions(context) {
        const { sourceFile, span } = context;
        const changes = textChanges.ChangeTracker.with(context, t => addMissingNewOperator(t, sourceFile, span));
        return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_new_operator_to_call, fixId, Diagnostics.Add_missing_new_operator_to_all_calls)];
    },
    fixIds: [fixId],
    getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
        addMissingNewOperator(changes, context.sourceFile, diag)),
});

function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan): void {
    const call = cast(findAncestorMatchingSpan(sourceFile, span), isCallExpression);
    const newExpression = factory.createNewExpression(call.expression, call.typeArguments, call.arguments);

    changes.replaceNode(sourceFile, call, newExpression);
}

function findAncestorMatchingSpan(sourceFile: SourceFile, span: TextSpan): Node {
    let token = getTokenAtPosition(sourceFile, span.start);
    const end = textSpanEnd(span);
    while (token.end < end) {
        token = token.parent;
    }
    return token;
}


text:
```
git clone https://github.com/googlegenomics/pipelines-api-examples.git
cd pipelines-api-examples/fastqc/
docker build -t ${USER}/fastqc .
```
## (2) Test locally the Docker image used by the pipeline.
```
./local/test_fastqc.sh
```

The result should be the newly created .html and .zip file in a subdirectory
on your local machine:
```
Copying test file NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311.bam to <snip>/pipelines-api-examples/src/test_mnt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 26534  100 26534    0     0   6983      0  0:00:03  0:00:03 --:--:--  6982

Running fastqc index via docker
Started analysis of NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311.bam
Analysis complete for NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311.bam

Execution completed

Scratch directory:
.
./output
./output/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311_fastqc.zip
./output/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311_fastqc.html
./input
./input/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311.bam
```

## (3) Push the Docker image to a repository.
In this example, we push the container to [Google Container Registry](https://cloud.google.com/container-registry/) via the following commands:
```
docker tag ${USER}/fastqc gcr.io/YOUR-PROJECT-ID/fastqc
gcloud docker -- push gcr.io/YOUR-PROJECT-ID/fastqc
```

## (4) Run the Docker image in the cloud
```
PYTHONPATH=.. python cloud/run_fastqc.py \
  --project YOUR-PROJECT-ID \
  --zones "us-*" \
  --disk-size 100 \
  --input \
    gs://genomics-public-data/ftp-trace.ncbi.nih.gov/1000genomes/ftp/technical/pilot3_exon_targetted_GRCh37_bams/data/NA06986/alignment/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311.bam \
    gs://genomics-public-data/ftp-trace.ncbi.nih.gov/1000genomes/ftp/technical/pilot3_exon_targetted_GRCh37_bams/data/NA18628/alignment/NA18628.chromY.LS454.ssaha2.CHB.exon_targetted.20100311.bam \
  --output gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output \
  --logging gs://YOUR-BUCKET/pipelines-api-examples/fastqc/logging \
  --poll-interval 20
```

* Replace `YOUR-PROJECT-ID` with your project ID.
* Replace `YOUR-BUCKET` with a bucket in your project.

The `PYTHONPATH` must include the top-level directory of the
`pipelines-api-examples` in order to pick up modules in the
[pipelines_pylib](../pipelines_pylib) directory.

The output will be the JSON description of the operation, followed by periodic
messages for polling. When the operation completes, the full operation will
be emitted.
```
{ u'done': False,
  u'metadata': { u'@type': u'type.googleapis.com/google.genomics.v1.OperationMetadata',
                 u'clientId': u'',
                 u'createTime': u'2016-03-10T02:01:42.000Z',
                 u'events': [],
                 u'projectId': u'YOUR-PROJECT-ID'},
  u'name': u'operations/YOUR-NEW-OPERATION-ID'}

Polling for completion of operation
Operation not complete. Sleeping 20 seconds
Operation not complete. Sleeping 20 seconds
...
Operation not complete. Sleeping 20 seconds

Operation complete

{ u'done': True,
  u'metadata': { u'@type': u'type.googleapis.com/google.genomics.v1.OperationMetadata',
                 u'clientId': u'',
                 u'createTime': u'2016-03-10T02:01:42.000Z',
                 u'endTime': u'2016-03-10T02:04:52.000Z',
                 u'events': [ { u'description': u'start(g1-small)',
                                u'startTime': u'2016-03-10T02:03:01.000Z'},
                              { u'description': u'pulling-image',
                                u'startTime': u'2016-03-10T02:03:11.000Z'},
                              { u'description': u'localizing-files',
                                u'startTime': u'2016-03-10T02:03:50.000Z'},
                              { u'description': u'running-docker',
                                u'startTime': u'2016-03-10T02:04:07.000Z'},
                              { u'description': u'delocalizing-files',
                                u'startTime': u'2016-03-10T02:04:29.000Z'},
                              { u'description': u'ok',
                                u'startTime': u'2016-03-10T02:04:43.000Z'}],
                 u'projectId': u'YOUR-PROJECT-ID',
                 u'request': { u'@type': u'type.googleapis.com/google.genomics.v1alpha2.RunPipelineRequest',
                               u'ephemeralPipeline': { u'description': u'Run "FastQC" on one or more files',
                                                       u'docker': { u'cmd': u'mkdir /mnt/data/output && fastqc /mnt/data/input/* --outdir=/mnt/data/output/',
                                                                    u'imageName': u'gcr.io/YOUR-PROJECT-ID/fastqc'},
                                                       u'name': u'fastqc',
                                                       u'parameters': [ { u'description': u'Cloud Storage path to an input file',
                                                                          u'name': u'inputFile0'},
                                                                        { u'description': u'Cloud Storage path to an input file',
                                                                          u'name': u'inputFile1'},
                                                                        { u'description': u'Cloud Storage path for where to FastQC output',
                                                                          u'name': u'outputPath'}],
                                                       u'projectId': u'YOUR-PROJECT-ID',
                                                       u'resources': { u'disks': [ { u'autoDelete': True,
                                                                                u'name': u'datadisk',
                                                                                u'sizeGb': 500,
                                                                                u'type': u'PERSISTENT_HDD'}],
                                                                       u'minimumCpuCores': 1,
                                                                       u'minimumRamGb': 3.75}},
                               u'pipelineArgs': { u'clientId': u'',
                                                  u'inputs': { u'inputFile0': u'gs://genomics-public-data/ftp-trace.ncbi.nih.gov/1000genomes/ftp/technical/pilot3_exon_targetted_GRCh37_bams/data/NA06986/alignment/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311.bam',
                                                               u'inputFile1': u'gs://genomics-public-data/ftp-trace.ncbi.nih.gov/1000genomes/ftp/technical/pilot3_exon_targetted_GRCh37_bams/data/NA18628/alignment/NA18628.chromY.LS454.ssaha2.CHB.exon_targetted.20100311.bam'},
                                                  u'logging': { u'gcsPath': u'gs://YOUR-BUCKET/pipelines-api-examples/fastqc/logging'},
                                                  u'outputs': { u'outputPath': u'gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output'},
                                                  u'projectId': u'YOUR-PROJECT-ID',
                                                  u'resources': { u'disks': [ { u'autoDelete': False,
                                                                                u'mountPoint': u'',
                                                                                u'name': u'datadisk',
                                                                                u'readOnly': False,
                                                                                u'sizeGb': 100,
                                                                                u'source': u'',
                                                                                u'type': u'PERSISTENT_HDD'}],
                                                                  u'minimumCpuCores': 0,
                                                                  u'minimumRamGb': 1,
                                                                  u'preemptible': False,
                                                                  u'zones': [ u'us-central1-a',
                                                                              u'us-central1-b',
                                                                              u'us-central1-c',
                                                                              u'us-central1-f']},
                                                  u'serviceAccount': { u'email': u'default',
                                                                       u'scopes': [ u'https://www.googleapis.com/auth/compute',
                                                                                u'https://www.googleapis.com/auth/devstorage.full_control',
                                                                                u'https://www.googleapis.com/auth/genomics']}}},
                 u'startTime': u'2016-03-10T02:02:09.000Z'},
  u'name': u'operations/YOUR-NEW-OPERATION-ID'}
```

## (5) Check the results

Check the operation output for a top-level `errors` field.
If none, then the operation should have finished successfully.

```
$ gsutil ls gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output
gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311_fastqc.html
gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output/NA06986.chromMT.ILLUMINA.bwa.CEU.exon_targetted.20100311_fastqc.zip
gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output/NA18628.chromY.LS454.ssaha2.CHB.exon_targetted.20100311_fastqc.html
gs://YOUR-BUCKET/pipelines-api-examples/fastqc/output/NA18628.chromY.LS454.ssaha2.CHB.exon_targetted.20100311_fastqc.zip
```


text:
use weather;
select @rownum := @rownum + 1 Rank
     , Name
     , Latitude
     , Longitude
     , Elevation
     , Latest
     , Readings
     , AvgTemp
     , MaxTemp
     , MinTemp
     , `Hot%`
     , `Warm%`
     , `Cold%`
     , `Cool%`
     , `Nice%`
     , AvgHumid
     , AvgDP
     , `Humid%`
     , `Rainy%`
FROM (select @rownum := 0) as r
   , (Select Xref.Name
     , Xref.Latitude
     , Xref.Longitude
     , Xref.Elevation
     , Date(max(ol.When)) Latest
     , count(*) Readings
     , Round(Avg(Temperature),1) AvgTemp
     , max(Temperature) MaxTemp
     , min(Temperature) MinTemp
     , coalesce(Round((ReallyHotDays / count(*))*100,1),0) `Hot%`
     , coalesce(Round((HotDays / count(*))*100,1),0) `Warm%`
     , coalesce(Round((ColdDays / count(*))*100,1),0) `Cold%`
     , coalesce(Round((CoolDays / count(*))*100,1),0) `Cool%`
     , coalesce(Round((NiceDays / count(*))*100,1),0) `Nice%`
     , Round(Avg(Humidity),1) AvgHumid
     , Round(Avg(CalcDewPoint),1) AvgDP
     , coalesce(Round((HumidDays / count(*))*100,1),0) `Humid%`
     , coalesce(Round((RainyDays / count(*))*100,1),0) `Rainy%`
  from vLog as ol
  join Xref
    on Xref.Station = ol.Station
  join (SELECT @rownum := 0) r
  left join (select Station
             , count(Distinct Date(`When`)) RainyDays
          from vLog il
         where RainRate > 0
       --    and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as rd
    on rd.Station = ol.Station
  left join (select Station
             , count(*) HumidDays
          from vLog il
         where CalcDewPoint > 69
           and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as sd
    on sd.Station = ol.Station
  left join (select Station
             , count(*) ReallyHotDays
          from vLog il
         where HeatIndex between 90 and 130
           and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as rhd
    on rhd.Station = ol.Station
  left join (select Station
             , count(*) HotDays
          from vLog il
         where HeatIndex between 80 and 90
           and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as hd
    on hd.Station = ol.Station
  left join (select Station
             , count(*) ColdDays
          from Log il
         where Temperature between -40 and 30
           and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as cd
    on cd.Station = ol.Station
  left join (select Station
             , count(*) CoolDays
          from Log il
         where Temperature between 30 and 50
           and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as coold
    on coold.Station = ol.Station
  left join (select Station
             , count(*) NiceDays
          from Log il
         where Temperature between 50 and 80
           and hour(il.When) = 14
           and date(il.When) >= '2012-01-01'
         group by Station) as nd
    on nd.Station = ol.Station
 where Temperature between -40 and 130
   and hour(ol.When) = 14
   and date(ol.When) >= '2012-01-01'
 group by Xref.Name) as x
 order by `Nice%` desc, `Humid%` asc
;


text:
package pieces100;

import static vgrechka.Jaco0.buildString;
import static vgrechka.Jaco0.ifNotNullv;

public class Style {
    public String accelerator;
    public String azimuth;
    public String background;
    public String backgroundAttachment;
    public String backgroundColor;
    public String backgroundImage;
    public String backgroundPosition;
    public String backgroundPositionX;
    public String backgroundPositionY;
    public String backgroundRepeat;
    public String behavior;
    public String border;
    public String borderBottom;
    public String borderBottomColor;
    public String borderBottomStyle;
    public String borderBottomWidth;
    public String borderCollapse;
    public String borderColor;
    public String borderLeft;
    public String borderLeftColor;
    public String borderLeftStyle;
    public String borderLeftWidth;
    public String borderRight;
    public String borderRightColor;
    public String borderRightStyle;
    public String borderRightWidth;
    public String borderSpacing;
    public String borderStyle;
    public String borderTop;
    public String borderTopColor;
    public String borderTopStyle;
    public String borderTopWidth;
    public String borderWidth;
    public String bottom;
    public String captionSide;
    public String clear;
    public String clip;
    public String color;
    public String content;
    public String counterIncrement;
    public String counterReset;
    public String cue;
    public String cueAfter;
    public String cueBefore;
    public String cursor;
    public String direction;
    public String display;
    public String elevation;
    public String emptyCells;
    public String filter;
    public String phloat;
    public String font;
    public String fontFamily;
    public String fontSize;
    public String fontSizeAdjust;
    public String fontStretch;
    public String fontStyle;
    public String fontVariant;
    public String fontWeight;
    public String height;
    public String imeMode;
    public String includeSource;
    public String layerBackgroundColor;
    public String layerBackgroundImage;
    public String layoutFlow;
    public String layoutGrid;
    public String layoutGridChar;
    public String layoutGridCharSpacing;
    public String layoutGridLine;
    public String layoutGridMode;
    public String layoutGridType;
    public String left;
    public String letterSpacing;
    public String lineBreak;
    public String lineHeight;
    public String listStyle;
    public String listStyleImage;
    public String listStylePosition;
    public String listStyleType;
    public String margin;
    public String marginBottom;
    public String marginLeft;
    public String marginRight;
    public String marginTop;
    public String markerOffset;
    public String marks;
    public String maxHeight;
    public String maxWidth;
    public String minHeight;
    public String minWidth;
    public String orphans;
    public String outline;
    public String outlineColor;
    public String outlineStyle;
    public String outlineWidth;
    public String overflow;
    public String overflowX;
    public String overflowY;
    public String padding;
    public String paddingBottom;
    public String paddingLeft;
    public String paddingRight;
    public String paddingTop;
    public String page;
    public String pageBreakAfter;
    public String pageBreakBefore;
    public String pageBreakInside;
    public String pause;
    public String pauseAfter;
    public String pauseBefore;
    public String pitch;
    public String pitchRange;
    public String playDuring;
    public String position;
    public String quotes;
    public String richness;
    public String right;
    public String rubyAlign;
    public String rubyOverhang;
    public String rubyPosition;
    public String size;
    public String speak;
    public String speakHeader;
    public String speakNumeral;
    public String speakPunctuation;
    public String speechRate;
    public String stress;
    public String scrollbarArrowColor;
    public String scrollbarBaseColor;
    public String scrollbarDarkShadowColor;
    public String scrollbarFaceColor;
    public String scrollbarHighlightColor;
    public String scrollbarShadowColor;
    public String scrollbar3dLightColor;
    public String scrollbarTrackColor;
    public String tableLayout;
    public String textAlign;
    public String textAlignLast;
    public String textDecoration;
    public String textIndent;
    public String textJustify;
    public String textOverflow;
    public String textShadow;
    public String textTransform;
    public String textAutospace;
    public String textKashidaSpace;
    public String textUnderlinePosition;
    public String top;
    public String unicodeBidi;
    public String verticalAlign;
    public String visibility;
    public String voiceFamily;
    public String volume;
    public String whiteSpace;
    public String widows;
    public String width;
    public String wordBreak;
    public String wordSpacing;
    public String wordWrap;
    public String writingMode;
    public String zIndex;
    public String zoom;
    public String borderRadius;
    public String flexGrow;
    public String borderTopLeftRadius;
    public String borderTopRightRadius ;
    public String alignItems;

    public String render() {
        return buildString(s -> {
            ifNotNullv(accelerator, it -> s.append("accelerator: " + it + ";"));
            ifNotNullv(azimuth, it -> s.append("azimuth: " + it + ";"));
            ifNotNullv(background, it -> s.append("background: " + it + ";"));
            ifNotNullv(backgroundAttachment, it -> s.append("background-attachment: " + it + ";"));
            ifNotNullv(backgroundColor, it -> s.append("background-color: " + it + ";"));
            ifNotNullv(backgroundImage, it -> s.append("background-image: " + it + ";"));
            ifNotNullv(backgroundPosition, it -> s.append("background-position: " + it + ";"));
            ifNotNullv(backgroundPositionX, it -> s.append("background-position-x: " + it + ";"));
            ifNotNullv(backgroundPositionY, it -> s.append("background-position-y: " + it + ";"));
            ifNotNullv(backgroundRepeat, it -> s.append("background-repeat: " + it + ";"));
            ifNotNullv(behavior, it -> s.append("behavior: " + it + ";"));
            ifNotNullv(border, it -> s.append("border: " + it + ";"));
            ifNotNullv(borderBottom, it -> s.append("border-bottom: " + it + ";"));
            ifNotNullv(borderBottomColor, it -> s.append("border-bottom-color: " + it + ";"));
            ifNotNullv(borderBottomStyle, it -> s.append("border-bottom-style: " + it + ";"));
            ifNotNullv(borderBottomWidth, it -> s.append("border-bottom-width: " + it + ";"));
            ifNotNullv(borderCollapse, it -> s.append("border-collapse: " + it + ";"));
            ifNotNullv(borderColor, it -> s.append("border-color: " + it + ";"));
            ifNotNullv(borderLeft, it -> s.append("border-left: " + it + ";"));
            ifNotNullv(borderLeftColor, it -> s.append("border-left-color: " + it + ";"));
            ifNotNullv(borderLeftStyle, it -> s.append("border-left-style: " + it + ";"));
            ifNotNullv(borderLeftWidth, it -> s.append("border-left-width: " + it + ";"));
            ifNotNullv(borderRight, it -> s.append("border-right: " + it + ";"));
            ifNotNullv(borderRightColor, it -> s.append("border-right-color: " + it + ";"));
            ifNotNullv(borderRightStyle, it -> s.append("border-right-style: " + it + ";"));
            ifNotNullv(borderRightWidth, it -> s.append("border-right-width: " + it + ";"));
            ifNotNullv(borderSpacing, it -> s.append("border-spacing: " + it + ";"));
            ifNotNullv(borderStyle, it -> s.append("border-style: " + it + ";"));
            ifNotNullv(borderTop, it -> s.append("border-top: " + it + ";"));
            ifNotNullv(borderTopColor, it -> s.append("border-top-color: " + it + ";"));
            ifNotNullv(borderTopStyle, it -> s.append("border-top-style: " + it + ";"));
            ifNotNullv(borderTopWidth, it -> s.append("border-top-width: " + it + ";"));
            ifNotNullv(borderWidth, it -> s.append("border-width: " + it + ";"));
            ifNotNullv(bottom, it -> s.append("bottom: " + it + ";"));
            ifNotNullv(captionSide, it -> s.append("caption-side: " + it + ";"));
            ifNotNullv(clear, it -> s.append("clear: " + it + ";"));
            ifNotNullv(clip, it -> s.append("clip: " + it + ";"));
            ifNotNullv(color, it -> s.append("color: " + it + ";"));
            ifNotNullv(content, it -> s.append("content: " + it + ";"));
            ifNotNullv(counterIncrement, it -> s.append("counter-increment: " + it + ";"));
            ifNotNullv(counterReset, it -> s.append("counter-reset: " + it + ";"));
            ifNotNullv(cue, it -> s.append("cue: " + it + ";"));
            ifNotNullv(cueAfter, it -> s.append("cue-after: " + it + ";"));
            ifNotNullv(cueBefore, it -> s.append("cue-before: " + it + ";"));
            ifNotNullv(cursor, it -> s.append("cursor: " + it + ";"));
            ifNotNullv(direction, it -> s.append("direction: " + it + ";"));
            ifNotNullv(display, it -> s.append("display: " + it + ";"));
            ifNotNullv(elevation, it -> s.append("elevation: " + it + ";"));
            ifNotNullv(emptyCells, it -> s.append("empty-cells: " + it + ";"));
            ifNotNullv(filter, it -> s.append("filter: " + it + ";"));
            ifNotNullv(phloat, it -> s.append("float: " + it + ";"));
            ifNotNullv(font, it -> s.append("font: " + it + ";"));
            ifNotNullv(fontFamily, it -> s.append("font-family: " + it + ";"));
            ifNotNullv(fontSize, it -> s.append("font-size: " + it + ";"));
            ifNotNullv(fontSizeAdjust, it -> s.append("font-size-adjust: " + it + ";"));
            ifNotNullv(fontStretch, it -> s.append("font-stretch: " + it + ";"));
            ifNotNullv(fontStyle, it -> s.append("font-style: " + it + ";"));
            ifNotNullv(fontVariant, it -> s.append("font-variant: " + it + ";"));
            ifNotNullv(fontWeight, it -> s.append("font-weight: " + it + ";"));
            ifNotNullv(height, it -> s.append("height: " + it + ";"));
            ifNotNullv(imeMode, it -> s.append("ime-mode: " + it + ";"));
            ifNotNullv(includeSource, it -> s.append("include-source: " + it + ";"));
            ifNotNullv(layerBackgroundColor, it -> s.append("layer-background-color: " + it + ";"));
            ifNotNullv(layerBackgroundImage, it -> s.append("layer-background-image: " + it + ";"));
            ifNotNullv(layoutFlow, it -> s.append("layout-flow: " + it + ";"));
            ifNotNullv(layoutGrid, it -> s.append("layout-grid: " + it + ";"));
            ifNotNullv(layoutGridChar, it -> s.append("layout-grid-char: " + it + ";"));
            ifNotNullv(layoutGridCharSpacing, it -> s.append("layout-grid-char-spacing: " + it + ";"));
            ifNotNullv(layoutGridLine, it -> s.append("layout-grid-line: " + it + ";"));
            ifNotNullv(layoutGridMode, it -> s.append("layout-grid-mode: " + it + ";"));
            ifNotNullv(layoutGridType, it -> s.append("layout-grid-type: " + it + ";"));
            ifNotNullv(left, it -> s.append("left: " + it + ";"));
            ifNotNullv(letterSpacing, it -> s.append("letter-spacing: " + it + ";"));
            ifNotNullv(lineBreak, it -> s.append("line-break: " + it + ";"));
            ifNotNullv(lineHeight, it -> s.append("line-height: " + it + ";"));
            ifNotNullv(listStyle, it -> s.append("list-style: " + it + ";"));
            ifNotNullv(listStyleImage, it -> s.append("list-style-image: " + it + ";"));
            ifNotNullv(listStylePosition, it -> s.append("list-style-position: " + it + ";"));
            ifNotNullv(listStyleType, it -> s.append("list-style-type: " + it + ";"));
            ifNotNullv(margin, it -> s.append("margin: " + it + ";"));
            ifNotNullv(marginBottom, it -> s.append("margin-bottom: " + it + ";"));
            ifNotNullv(marginLeft, it -> s.append("margin-left: " + it + ";"));
            ifNotNullv(marginRight, it -> s.append("margin-right: " + it + ";"));
            ifNotNullv(marginTop, it -> s.append("margin-top: " + it + ";"));
            ifNotNullv(markerOffset, it -> s.append("marker-offset: " + it + ";"));
            ifNotNullv(marks, it -> s.append("marks: " + it + ";"));
            ifNotNullv(maxHeight, it -> s.append("max-height: " + it + ";"));
            ifNotNullv(maxWidth, it -> s.append("max-width: " + it + ";"));
            ifNotNullv(minHeight, it -> s.append("min-height: " + it + ";"));
            ifNotNullv(minWidth, it -> s.append("min-width: " + it + ";"));
            ifNotNullv(orphans, it -> s.append("orphans: " + it + ";"));
            ifNotNullv(outline, it -> s.append("outline: " + it + ";"));
            ifNotNullv(outlineColor, it -> s.append("outline-color: " + it + ";"));
            ifNotNullv(outlineStyle, it -> s.append("outline-style: " + it + ";"));
            ifNotNullv(outlineWidth, it -> s.append("outline-width: " + it + ";"));
            ifNotNullv(overflow, it -> s.append("overflow: " + it + ";"));
            ifNotNullv(overflowX, it -> s.append("overflow-x: " + it + ";"));
            ifNotNullv(overflowY, it -> s.append("overflow-y: " + it + ";"));
            ifNotNullv(padding, it -> s.append("padding: " + it + ";"));
            ifNotNullv(paddingBottom, it -> s.append("padding-bottom: " + it + ";"));
            ifNotNullv(paddingLeft, it -> s.append("padding-left: " + it + ";"));
            ifNotNullv(paddingRight, it -> s.append("padding-right: " + it + ";"));
            ifNotNullv(paddingTop, it -> s.append("padding-top: " + it + ";"));
            ifNotNullv(page, it -> s.append("page: " + it + ";"));
            ifNotNullv(pageBreakAfter, it -> s.append("page-break-after: " + it + ";"));
            ifNotNullv(pageBreakBefore, it -> s.append("page-break-before: " + it + ";"));
            ifNotNullv(pageBreakInside, it -> s.append("page-break-inside: " + it + ";"));
            ifNotNullv(pause, it -> s.append("pause: " + it + ";"));
            ifNotNullv(pauseAfter, it -> s.append("pause-after: " + it + ";"));
            ifNotNullv(pauseBefore, it -> s.append("pause-before: " + it + ";"));
            ifNotNullv(pitch, it -> s.append("pitch: " + it + ";"));
            ifNotNullv(pitchRange, it -> s.append("pitch-range: " + it + ";"));
            ifNotNullv(playDuring, it -> s.append("play-during: " + it + ";"));
            ifNotNullv(position, it -> s.append("position: " + it + ";"));
            ifNotNullv(quotes, it -> s.append("quotes: " + it + ";"));
            ifNotNullv(richness, it -> s.append("richness: " + it + ";"));
            ifNotNullv(right, it -> s.append("right: " + it + ";"));
            ifNotNullv(rubyAlign, it -> s.append("ruby-align: " + it + ";"));
            ifNotNullv(rubyOverhang, it -> s.append("ruby-overhang: " + it + ";"));
            ifNotNullv(rubyPosition, it -> s.append("ruby-position: " + it + ";"));
            ifNotNullv(size, it -> s.append("size: " + it + ";"));
            ifNotNullv(speak, it -> s.append("speak: " + it + ";"));
            ifNotNullv(speakHeader, it -> s.append("speak-header: " + it + ";"));
            ifNotNullv(speakNumeral, it -> s.append("speak-numeral: " + it + ";"));
            ifNotNullv(speakPunctuation, it -> s.append("speak-punctuation: " + it + ";"));
            ifNotNullv(speechRate, it -> s.append("speech-rate: " + it + ";"));
            ifNotNullv(stress, it -> s.append("stress: " + it + ";"));
            ifNotNullv(scrollbarArrowColor, it -> s.append("scrollbar-arrow-color: " + it + ";"));
            ifNotNullv(scrollbarBaseColor, it -> s.append("scrollbar-base-color: " + it + ";"));
            ifNotNullv(scrollbarDarkShadowColor, it -> s.append("scrollbar-dark-shadow-color: " + it + ";"));
            ifNotNullv(scrollbarFaceColor, it -> s.append("scrollbar-face-color: " + it + ";"));
            ifNotNullv(scrollbarHighlightColor, it -> s.append("scrollbar-highlight-color: " + it + ";"));
            ifNotNullv(scrollbarShadowColor, it -> s.append("scrollbar-shadow-color: " + it + ";"));
            ifNotNullv(scrollbar3dLightColor, it -> s.append("scrollbar-3d-light-color: " + it + ";"));
            ifNotNullv(scrollbarTrackColor, it -> s.append("scrollbar-track-color: " + it + ";"));
            ifNotNullv(tableLayout, it -> s.append("table-layout: " + it + ";"));
            ifNotNullv(textAlign, it -> s.append("text-align: " + it + ";"));
            ifNotNullv(textAlignLast, it -> s.append("text-align-last: " + it + ";"));
            ifNotNullv(textDecoration, it -> s.append("text-decoration: " + it + ";"));
            ifNotNullv(textIndent, it -> s.append("text-indent: " + it + ";"));
            ifNotNullv(textJustify, it -> s.append("text-justify: " + it + ";"));
            ifNotNullv(textOverflow, it -> s.append("text-overflow: " + it + ";"));
            ifNotNullv(textShadow, it -> s.append("text-shadow: " + it + ";"));
            ifNotNullv(textTransform, it -> s.append("text-transform: " + it + ";"));
            ifNotNullv(textAutospace, it -> s.append("text-autospace: " + it + ";"));
            ifNotNullv(textKashidaSpace, it -> s.append("text-kashida-space: " + it + ";"));
            ifNotNullv(textUnderlinePosition, it -> s.append("text-underline-position: " + it + ";"));
            ifNotNullv(top, it -> s.append("top: " + it + ";"));
            ifNotNullv(unicodeBidi, it -> s.append("unicode-bidi: " + it + ";"));
            ifNotNullv(verticalAlign, it -> s.append("vertical-align: " + it + ";"));
            ifNotNullv(visibility, it -> s.append("visibility: " + it + ";"));
            ifNotNullv(voiceFamily, it -> s.append("voice-family: " + it + ";"));
            ifNotNullv(volume, it -> s.append("volume: " + it + ";"));
            ifNotNullv(whiteSpace, it -> s.append("white-space: " + it + ";"));
            ifNotNullv(widows, it -> s.append("widows: " + it + ";"));
            ifNotNullv(width, it -> s.append("width: " + it + ";"));
            ifNotNullv(wordBreak, it -> s.append("word-break: " + it + ";"));
            ifNotNullv(wordSpacing, it -> s.append("word-spacing: " + it + ";"));
            ifNotNullv(wordWrap, it -> s.append("word-wrap: " + it + ";"));
            ifNotNullv(writingMode, it -> s.append("writing-mode: " + it + ";"));
            ifNotNullv(zIndex, it -> s.append("z-index: " + it + ";"));
            ifNotNullv(zoom, it -> s.append("zoom: " + it + ";"));
            ifNotNullv(borderRadius, it -> s.append("border-radius: " + it + ";"));
            ifNotNullv(flexGrow, it -> s.append("flex-grow: " + it + ";"));
            ifNotNullv(borderTopLeftRadius, it -> s.append("border-top-left-radius: " + it + ";"));
            ifNotNullv(borderTopRightRadius, it -> s.append("border-top-right-radius: " + it + ";"));
            ifNotNullv(alignItems, it -> s.append("align-items: " + it + ";"));
        });
    }
}


text:
package com.webimageloader.util;

import android.graphics.Bitmap;
import com.webimageloader.ImageLoader;
import com.webimageloader.Request;
import com.webimageloader.transformation.Transformation;

import java.io.IOException;

public abstract class AbstractImageLoader implements ImageLoader {
    @Override
    public Bitmap loadBlocking(String url) throws IOException {
        return loadBlocking(new Request(url));
    }

    @Override
    public Bitmap loadBlocking(String url, Transformation transformation) throws IOException {
        return loadBlocking(new Request(url, transformation));
    }

    @Override
    public void preload(String url) {
        preload(new Request(url));
    }

    @Override
    public void preload(String url, Transformation transformation) {
        preload(new Request(url, transformation));
    }

    @Override
    public <T> Bitmap load(T tag, String url, Listener<T> listener) {
        return load(tag, new Request(url), listener);
    }

    @Override
    public <T> Bitmap load(T tag, String url, Transformation transformation, Listener<T> listener) {
        return load(tag, new Request(url, transformation), listener);
    }
}


text:
const PooledRider = require('./pooledRider')

const MIN_INTERVAL = 2500;
const RATE_LIMIT = parseInt(process.env.ZwiftRateLimit || "5");
const MAX_RATE = RATE_LIMIT * 0.5;

class RiderPool {
  constructor(account) {
    this.account = account;

    this.riders = {};
    this.timeout = null;
  }

  riderStatus(riderId) {
    if (!this.riders[riderId]) {
        this.riders[riderId] = new PooledRider(this.account, riderId);
        console.log(`added ${riderId} (${this.list().length})`);
        this.trigger();
    }

    return this.riders[riderId].status()
  }

  trigger() {
    const count = this.list().length;
    if (!this.timeout && count > 0) {
        const delay = Math.max(1000 * count / MAX_RATE, MIN_INTERVAL);
        this.timeout = setTimeout(() => this.refreshAll(), delay);
    }
  }

  refreshAll() {
    let refreshList = [];
    this.list().forEach(rider => {
        if (rider.isStale) {
            delete this.riders[rider.id];
            console.log(`removed ${rider.id} (${this.list().length})`);
        } else {
            refreshList.push(rider);
        }
    });

    refreshNext();
    this.timeout = null;
    this.trigger();

    function refreshNext() {
        if (refreshList.length > 0) {
            const chunk = Math.max(1, Math.ceil(Math.min(refreshList.length / 5, 2 * MAX_RATE)));
            const riders = refreshList.splice(0, chunk);
            const promises = riders.map(r => r.refresh());
            Promise.all(promises).then(() => refreshNext());
        }
    }
  }

  list() {
      const list = [];
      for(const id in this.riders) {
          list.push(this.riders[id]);
      }
      return list;
  }
}

module.exports = RiderPool


text:
<?php

/**
 *
 * @package    swToolboxPlugin
 * @subpackage debug
 * @author     Sebastian Schmidt <info@schmidt-seb.de>
 * @version    SVN: $Id$
 */
class swTestDoctrineFormatter extends swTestFunctionalFormatter {
  public function getHeader() {
    return '<?php

include(dirname(__FILE__).\'/../../bootstrap/functional.php\');

$browser = new sfTestFunctional(new sfBrowser());
$test    = $browser->test();
$conn    = Doctrine::getConnectionByTableName(\'your_model\');

$conn->beginTransaction();';
  }

  public function getFooter() {
    return '$conn->rollback();';
  }
}


text:
VERFILES=acls.fst acls2.fst
include ../Makefile.include
all: .all.ver
#statefulEnc-single.vv statefulEnc-multi.vv statefulEnc-multi-hyperheap.vv
# statefulEnc-multi-frame.vv


text:
<?xml version="1.0" encoding="UTF-8"?>
<info>
	<uuid>00000000000000000000</uuid>
	<name>cc3200button</name>
	<description>TI CC3200 launchpad example</description>
	<company>Nsynapse Inc.</company>
	<developer>Byunghun Hwang</developer>
	<email>bhhwang@nsynapse.com</email>
	<url>http://www.nsynapse.com</url>
	<license>MIT</license>
	<version>0.0.1</version>
	<category></category>
	<tags></tags>
	<publish>service/cc3200button</publish>
	<subscribe>null</subscribe>
</info>

<property>
	<host>172.30.1.27</host>
	<port>8000</port>
</property>


text:
Making Poo the card game in Python

Built using Python 3.5


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one or more
  ~ contributor license agreements.  See the NOTICE file distributed with
  ~ this work for additional information regarding copyright ownership.
  ~ The ASF licenses this file to You under the Apache License, Version 2.0
  ~ (the "License"); you may not use this file except in compliance with
  ~ the License.  You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/spring
        http://camel.apache.org/schema/spring/camel-spring.xsd">

    <camelContext id="test" xmlns="http://camel.apache.org/schema/spring">

        <serviceCallConfiguration id="conf1">
            <staticServiceDiscovery>
                <servers>localhost:9091</servers>
            </staticServiceDiscovery>
        </serviceCallConfiguration>

        <serviceCallConfiguration id="conf2">
            <staticServiceDiscovery>
                <servers>localhost:9092</servers>
                <servers>localhost:9093,localhost:9094</servers>
            </staticServiceDiscovery>
        </serviceCallConfiguration>

        <route id="test1">
            <from uri="direct:start1"/>
            <serviceCall name="test" configurationRef="conf1"/>
        </route>
        <route id="test2">
            <from uri="direct:start2"/>
            <serviceCall name="test" configurationRef="conf2"/>
        </route>

    </camelContext>

</beans>


text:
package com.xson.util;

public final class Unicode {
    /**
     * 字符串转换unicode
     */
    public static String string2Unicode(String string) {

        StringBuilder unicode = new StringBuilder();

        for (int i = 0; i < string.length(); i++) {

            // 取出每一个字符
            char c = string.charAt(i);

            // 转换为unicode
            unicode.append("\\u").append(Integer.toHexString(c));
        }

        return unicode.toString();
    }

    /**
     * unicode 转字符串
     */
    public static String unicode2String(String unicode) {

        StringBuilder string = new StringBuilder();

        String[] hex = unicode.split("\\\\u");

        for (int i = 1; i < hex.length; i++) {

            // 转换出每一个代码点
            int data = Integer.parseInt(hex[i], 16);

            // 追加成string
            string.append((char) data);
        }

        return string.toString();
    }
}


text:
title: "Draft Article"
date: 2012-06-19
published: false
---

This is a draft