text:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace Dice.PbP
{
    /// <summary>
    /// Represents a post (such as in a Play-by-Post) that contains one or more rolls.
    /// <para>This class contains utilities that let you store results for multiple rolls in a single post,
    /// get those results back without changing the rolled values, and check for evidence of roll tampering/cheating.</para>
    /// </summary>
    [Serializable]
    public class RollPost : ISerializable, IDeserializationCallback
    {
        private List<RollResult> _pristine = new List<RollResult>();
        private List<RollResult> _stored = new List<RollResult>();
        private List<RollResult> _current = new List<RollResult>();

        /// <summary>
        /// Contains the "pristine" version of the post. This is used in cheat detection, as it should be a prefix of Current.
        /// If Pristine and Current diverge (as opposed to Current just having more elements), the post is flagged as being tampered with.
        /// </summary>
        public IReadOnlyList<RollResult> Pristine => _pristine;

        /// <summary>
        /// Mutable version of Pristine. Subclasses can modify the list via this method.
        /// </summary>
        protected IList<RollResult> PristineList { get; private set; }

        /// <summary>
        /// Contains the most recent saved version of the post. All rolls in the post are represented here in-order so that their results may be
        /// directly used rather than needing to re-evaluate the dice expression each time the post is viewed/previewed/edited.
        /// </summary>
        public IReadOnlyList<RollResult> Stored => _stored;

        /// <summary>
        /// Mutable version of Stored. Subclasses can modify the list via this method.
        /// </summary>
        protected IList<RollResult> StoredList { get; private set; }

        /// <summary>
        /// Contains the current version of the post (the one being checked). This starts out empty even when deserializing, and is added to
        /// via AddRoll().
        /// </summary>
        public IReadOnlyList<RollResult> Current => _current;

        /// <summary>
        /// Mutable version of Current. Subclasses can modify the list via this method.
        /// </summary>
        protected IList<RollResult> CurrentList { get; private set; }

        /// <summary>
        /// Getter is marked internal for unit testing, to ensure serialization roundtrips correctly.
        /// </summary>
        internal int Diverged { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="RollPost"/> class with default values.
        /// This represents a new post being made. If editing an existing post, the RollPost should be constructed
        /// via deserializing the old RollPost stored in the database or other storage medium.
        /// </summary>
        public RollPost() {
            PristineList = _pristine;
            StoredList = _stored;
            CurrentList = _current;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RollPost"/> class with existing data.
        /// This should be used whenever creating a RollPost based on an existing post.
        /// </summary>
        /// <param name="info">Serialization info.</param>
        /// <param name="context">Serialization streaming context.</param>
        protected RollPost(SerializationInfo info, StreamingContext context)
            : this()
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            // array is deserialized before contents, so cannot do .ToList() to save directly in _pristine and _stored
            // as such, save to these lists instead for the time being, then fix when all is done.
            int version = info.GetInt32("_Version");
            PristineList = (RollResult[])info.GetValue("Pristine", typeof(RollResult[]));
            StoredList = (RollResult[])info.GetValue("Stored", typeof(RollResult[]));
            CurrentList = new List<RollResult>();

            if (version >= 2 && context.State != StreamingContextStates.Persistence)
            {
                // when deserializing persisted data, current/diverged should have default values
                CurrentList = (RollResult[])info.GetValue("Current", typeof(RollResult[]));
                Diverged = info.GetInt32("Diverged");
            }
        }

        /// <summary>
        /// Serializes binary data to the given stream. This will *not* roundtrip (when deserializing Current will be empty).
        /// This method should be called when serializing this object to the database, to ensure that it is deserialized in the correct state.
        /// <para>BINARY SERIALIZATION IS NOT SAFE. You should prefer to serialize to JSON or XML rather than call this method.</para>
        /// </summary>
        /// <param name="serializationStream">Stream to write serialized data to.</param>
        public void Serialize(Stream serializationStream)
        {
            var formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Persistence));
            formatter.Serialize(serializationStream, this);
        }

        /// <summary>
        /// Deserializes binary data from the given stream, that data must have been serialized via RollPost.Serialize().
        /// <para>THIS METHOD IS NOT SAFE TO CALL ON UNTRUSTED INPUT.</para>
        /// </summary>
        /// <param name="serializationStream">Stream to read serialized data from.</param>
        /// <returns>Returns the deserialized RollPost.</returns>
        public static RollPost Deserialize(Stream serializationStream)
        {
            var formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Persistence));
            return (RollPost)formatter.Deserialize(serializationStream);
        }

        /// <summary>
        /// Completes deserialization of the RollPost once the entire object graph has been deserialized.
        /// <para>This method should not be directly called.</para>
        /// </summary>
        /// <param name="sender">Unused.</param>
        public virtual void OnDeserialization(object sender)
        {
            _pristine = PristineList.ToList();
            _stored = StoredList.ToList();
            _current = CurrentList.ToList();
            PristineList = _pristine;
            StoredList = _stored;
            CurrentList = _current;
        }

        /// <summary>
        /// Serializes a RollPost.
        /// <para>This method should not be directly called, use Serialize() instead.</para>
        /// </summary>
        /// <param name="info">Serialization information.</param>
        /// <param name="context">Serialization streaming context.</param>
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            // in v2, we roundtrip this as-is
            info.AddValue("_Version", 2);
            info.AddValue("Pristine", _pristine.ToArray(), typeof(RollResult[]));
            info.AddValue("Stored", _stored.ToArray(), typeof(RollResult[]));
            info.AddValue("Current", _current.ToArray(), typeof(RollResult[]));
            info.AddValue("Diverged", Diverged);
        }

        /// <summary>
        /// Adds a new roll to the post using the DefaultConfig if the roll needs to be evaluated.
        /// </summary>
        /// <param name="diceExpr">The dice expression to add, will be evaluated then added to the end of Current.</param>
        public void AddRoll(string diceExpr)
        {
            AddRoll(diceExpr, null, null);
        }

        /// <summary>
        /// Adds a new roll to the post using the given config if the roll needs to be evaluated.
        /// </summary>
        /// <param name="diceExpr">The dice expression to add, will be evaluated then added to the end of Current.</param>
        /// <param name="config">The configuration used for the roll. If null, RollerConfig.Default is used.</param>
        public void AddRoll(string diceExpr, RollerConfig? config)
        {
            AddRoll(diceExpr, config, null);
        }

        /// <summary>
        /// Adds a new roll to the post using the given config if the roll needs to be evaluated, and with additional data.
        /// </summary>
        /// <param name="diceExpr">The dice expression to add, will be evaluated then added to the end of Current.</param>
        /// <param name="config">The configuration used for the roll. If null, RollerConfig.Default is used.</param>
        /// <param name="data">Additional data that is scoped to this roll.</param>
        public void AddRoll(string diceExpr, RollerConfig? config, RollData? data)
        {
            if (config == null)
            {
                config = Roller.DefaultConfig;
            }

            if (data == null)
            {
                data = new RollData();
            }

            data.Config = config;
            data.MacroRegistry.RegisterMacro("roll", RollMacro);

            int nextIdx = Current.Count;
            AST.DiceAST ast;
            string normalizedExpr;
            var pristineVersion = _pristine.ElementAtOrDefault(nextIdx);
            var storedVersion = _stored.ElementAtOrDefault(nextIdx);

            try
            {
                ast = Roller.Parse(diceExpr, data);
                normalizedExpr = ast.ToString();

                // as later rolls may have macros that refer to earlier ones, we don't want to break out into a new roll
                // and then re-use a previously-rolled value. If we do, those saved macros may be incorrect.
                // As such, when we detect a divergence (pristine->stored->new roll), we ensure that we don't go back to
                // a previous state (so no stored->pristine or new roll->stored).
                if (Diverged == 0 && normalizedExpr == pristineVersion?.Expression)
                {
                    // use the pristine result for this roll
                    _current.Add(pristineVersion);
                }
                else if (Diverged == 0 && pristineVersion?.Expression == RollResult.InvalidRoll.Expression)
                {
                    // pristine was previously invalid and we now have a valid roll, so roll what we have and adjust pristine
                    var roll = Roller.Roll(ast, data);
                    _current.Add(roll);
                    _pristine[nextIdx] = roll;
                }
                else if (Diverged <= 1 && normalizedExpr == storedVersion?.Expression)
                {
                    _current.Add(storedVersion);
                    Diverged = 1;
                }
                else if (Diverged <= 1 && storedVersion?.Expression == RollResult.InvalidRoll.Expression)
                {
                    var roll = Roller.Roll(ast, data);
                    _current.Add(roll);
                    _stored[nextIdx] = roll;
                    Diverged = 1;
                }
                else
                {
                    // none of the versions for the current index matched, so reroll it
                    _current.Add(Roller.Roll(ast, data));
                    Diverged = 2;
                }
            }
            catch (DiceException)
            {
                // if this roll does not parse or had a roll error, we want to still save that fact so if the user later edits their post
                // to fix the roll, it does not invalidate any rolls which happen afterwards. Additionally, if a user
                // edits their post to make a roll invalid, we want to catch that and react accordingly.
                normalizedExpr = RollResult.InvalidRoll.Expression;

                if (Diverged == 0 && normalizedExpr == pristineVersion?.Expression)
                {
                    // pristine was invalid as well, so this expression was never fixed
                    _current.Add(pristineVersion);
                }
                else if (Diverged <= 1 && normalizedExpr == storedVersion?.Expression)
                {
                    _current.Add(storedVersion);
                    Diverged = 1;
                }
                else
                {
                    // brand new invalid roll, or modified a previously-good roll to be invalid
                    _current.Add(RollResult.InvalidRoll);
                    Diverged = 2;
                }

                // re-throw our error so it can be shownt to the user
                throw;
            }
        }

        /// <summary>
        /// Checks if Current has diverged from Pristine. If it has, this returns false and indicates that there was
        /// some tampering of the dice expressions (cheating). If it hasn't, this returns true to indicate that everything is good.
        /// <para>Additionally, if this succeeds, Pristine is set to Current.</para>
        /// <para>If you wish to add your own checks, extend RollPost in your own class and override Validate. Call the base
        /// Validate() only if your own checks all succeed. Otherwise, you may accidentally overwrite Pristine on validation failure.</para>
        /// </summary>
        /// <returns>Returns true if no tampering is detected, false otherwise.</returns>
        public virtual bool Validate()
        {
            // update _stored
            _stored = _current;

            if (_current.Count < _pristine.Count)
            {
                // rolls were removed
                return false;
            }

            if (!_pristine.SequenceEqual(_current.Take(_pristine.Count)))
            {
                // beginning of each doesn't match
                return false;
            }

            // if we get here, all is well
            _pristine = _current;

            return true;
        }

        /// <summary>
        /// Test if two RollPosts have diverged. Much like Validate, two RollPosts are considered to be divergent if one is not
        /// a prefix of the other.
        /// </summary>
        /// <param name="other">RollPost to check against.</param>
        /// <returns>True if the two RollPosts have diverged, false if they have not.</returns>
        public virtual bool HasDivergedFrom(RollPost other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            var ourList = Current.Count == 0 ? Stored : Current;
            var otherList = other.Current.Count == 0 ? other.Stored : other.Current;

            // To simplify logic, we only consider this case where 'this' is the larger of the two lists
            if (otherList.Count > ourList.Count)
            {
                return other.HasDivergedFrom(this);
            }

            var isSame = otherList.SequenceEqual(ourList.Take(otherList.Count));

            return !isSame;
        }

        private void RollMacro(MacroContext context)
        {
            // [roll:X] retrieves the Value of the Xth roll (first roll in the post is X=1). Can only retrieve values of past rolls.
            // [roll:X:Y] retrieves the Value of the Yth die on the Xth roll (actual die rolls only, aka normal/fudge/group). First die is Y=1.
            // [roll:X:critical] is the number of dice in the Xth roll that are critical.
            // [roll:X:Y:critical] is 1 if the Yth die is critical and 0 otherwise.
            // [roll:X:fumble] and [roll:X:Y:fumble] work the same way
            // as do [roll:X:success], [roll:X:Y:success], [roll:X:failure], and [roll:X:Y:failure]
            // for success/failure, it only counts number of successes or number of failures, returning an integer >= 0 for each. In other words,
            // [roll:X:success] doesn't deduct 1 whenever it sees a failure roll, unlike [roll:X] which will give successes - failures.
            // All other formulations of the macro are an error (which we pass down, as someone else may have their own roll macro which implements extended features)
            var args = context.Arguments;

            if (args.Count == 1)
            {
                return; // no X
            }

            if (!Int32.TryParse(args[1], out int rollIdx))
            {
                return; // invalid X
            }

            if (rollIdx < 0)
            {
                // negative X means we count backwards from the current post
                rollIdx += Current.Count;
            }
            else
            {
                rollIdx--; // make 0-based instead of 1-based
            }

            if (rollIdx < 0 || rollIdx >= Current.Count)
            {
                return; // X is too big or small
            }

            if (args.Count == 2)
            {
                // only have 2 args, return the value of the Xth roll
                context.Value = Current[rollIdx].Value;
                context.ValueType = Current[rollIdx].ResultType;
                return;
            }

            int nextIdx = 2;
            var allRolls = Current[rollIdx].Values.Where(d => d.IsLiveDie() && d.DieType.IsRoll()).ToList();
            if (Int32.TryParse(args[2], out int dieIdx))
            {
                dieIdx--;
                nextIdx = 3;
                if (dieIdx < 0 || dieIdx >= allRolls.Count)
                {
                    return; // Y is too big or small
                }

                if (args.Count == 3)
                {
                    // only have 3 args, X and Y. Return the value of the Yth roll
                    context.Value = allRolls[dieIdx].Value;
                    return;
                }
            }
            else
            {
                dieIdx = -1;
            }

            DieFlags flag;
            switch (args[nextIdx].ToLowerInvariant())
            {
                case "critical":
                    flag = DieFlags.Critical;
                    break;
                case "fumble":
                    flag = DieFlags.Fumble;
                    break;
                case "success":
                    flag = DieFlags.Success;
                    break;
                case "failure":
                    flag = DieFlags.Failure;
                    break;
                default:
                    return; // unrecognized flag
            }

            if (dieIdx >= 0)
            {
                context.Value = allRolls[dieIdx].Flags.HasFlag(flag) ? 1 : 0;
            }
            else
            {
                context.Value = allRolls.Count(d => d.Flags.HasFlag(flag));
            }
        }
    }
}


text:
const path = require('path');

const gulp = require('gulp');
const del = require('del');
const filter = require('gulp-filter');

const conf = require('../conf/gulp.conf');

gulp.task('clean', clean);
gulp.task('clean:dev', cleanDev);
gulp.task('clean:dist', cleanDist);
gulp.task('other', other);

function clean() {
  return del([conf.paths.dist, conf.paths.tmp]);
}

function cleanDev() {
    return del([conf.paths.tmp]);
}

function cleanDist() {
    return del([conf.paths.dist]);
}

function other() {
  const fileFilter = filter(file => file.stat.isFile());

  return gulp.src([
    path.join(conf.paths.src, '/**/*'),
    path.join(`!${conf.paths.src}`, '/**/*.{html,css,js,scss}')
  ])
    .pipe(fileFilter)
    .pipe(gulp.dest(conf.paths.dist));
}

redpajama_set_name: RedPajamaGithub


text:
set -euo pipefail

export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
export COPYFILE_DISABLE=true

INPUT_FILE=$1
EXPLODED=$2.exploded
USERNAME=$3
PASSWORD=$4

set -x

CODESIGN_STRING=$5
JDK_ARCHIVE="$6"
NOTARIZE=$7
BUNDLE_ID=$8
COMPRESS_INPUT=${9:-false}

cd "$(dirname "$0")"

function log() {
  echo "$(date '+[%H:%M:%S]') $*"
}

function retry() {
  local operation=$1
  local limit=$2
  local stop_code=23
  shift
  shift
  local attempt=1
  while true; do
    # shellcheck disable=SC2015
    "$@" && { log "$operation done"; return 0; } || {
      ec=$?
      if [[ "$ec" == "$stop_code" ]]; then
        log "$operation failed with exit code $ec, no more attempts."
        return $ec
      fi
      if [[ $attempt -ge limit ]]; then
        log "$operation failed with exit code $ec. Attempt $attempt/$limit."
        return $ec
      fi
      log "$operation failed with exit code $ec. Attempt $attempt/$limit, will wait 30 seconds before next attempt."
      sleep 30;
      ((attempt++))
    }
  done
}

log "Deleting $EXPLODED ..."
if test -d "$EXPLODED"; then
  find "$EXPLODED" -mindepth 1 -maxdepth 1 -exec chmod -R u+wx '{}' \;
fi
rm -rf "$EXPLODED"
mkdir "$EXPLODED"

log "Unzipping $INPUT_FILE to $EXPLODED ..."
unzip -q -o "$INPUT_FILE" -d "$EXPLODED"
rm "$INPUT_FILE"
BUILD_NAME="$(ls "$EXPLODED")"
log "$INPUT_FILE unzipped and removed"

APPLICATION_PATH="$EXPLODED/$BUILD_NAME"

if [ "$JDK_ARCHIVE" != "no-jdk" ] && [ -f "$JDK_ARCHIVE" ]; then
  log "Copying JDK: $JDK_ARCHIVE to $APPLICATION_PATH/Contents"
  tar xvf "$JDK_ARCHIVE" -C "$APPLICATION_PATH/Contents"
  find "$APPLICATION_PATH/Contents/" -mindepth 1 -maxdepth 1 -exec chmod -R u+w '{}' \;
  log "JDK has been copied"
  rm -f "$JDK_ARCHIVE"
fi

find "$APPLICATION_PATH/Contents/bin" \
  -maxdepth 1 -type f -name '*.jnilib' -print0 |
  while IFS= read -r -d $'\0' file; do
    if [ -f "$file" ]; then
      log "Linking $file"
      b="$(basename "$file" .jnilib)"
      ln -sf "$b.jnilib" "$(dirname "$file")/$b.dylib"
    fi
  done

find "$APPLICATION_PATH/Contents/" \
  -maxdepth 1 -type f -name '*.txt' -print0 |
  while IFS= read -r -d $'\0' file; do
    if [ -f "$file" ]; then
      log "Moving $file"
      mv "$file" "$APPLICATION_PATH/Contents/Resources"
    fi
  done

non_plist=$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist' | wc -l)
if [[ $non_plist -gt 0 ]]; then
  log "Only Info.plist file is allowed in Contents directory but found $non_plist file(s):"
  log "$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist')"
  exit 1
fi

if [ "$CODESIGN_STRING" != "" ]; then
  log "Unlocking keychain..."
  # Make sure *.p12 is imported into local KeyChain
  set +x
  security unlock-keychain -p "$PASSWORD" "/Users/$USERNAME/Library/Keychains/login.keychain"
  set -x

  log "Signing ..."
  retry "Signing" 3 ./sign.sh "$APPLICATION_PATH" "$CODESIGN_STRING"

  log "Checking code signature ..."
  codesign -v "$APPLICATION_PATH" -vvvvv
  log "Check sign done"
else
  log "Signing is disabled"
fi

set -e

if [ "$NOTARIZE" = "yes" ]; then
  log "Notarizing..."
  # shellcheck disable=SC1090
  source "$HOME/.notarize_token"
  APP_NAME="${INPUT_FILE%.*}"
  # Since notarization tool uses same file for upload token we have to trick it into using different folders, hence fake root
  # Also it leaves copy of zip file in TMPDIR, so notarize.sh overrides it and uses FAKE_ROOT as location for temp TMPDIR
  FAKE_ROOT="$(pwd)/fake-root"
  mkdir -p "$FAKE_ROOT"
  echo "Notarization will use fake root: $FAKE_ROOT"
  set +x
  retry "Notarization" 3 ./notarize.sh "$APPLICATION_PATH" "$APPLE_USERNAME" "$APPLE_PASSWORD" "$APP_NAME" "$BUNDLE_ID" "$FAKE_ROOT"
  set -x
  rm -rf "$FAKE_ROOT"

  log "Stapling..."
  retry "Stapling" 3 xcrun stapler staple "$APPLICATION_PATH"
else
  log "Notarization disabled"
  log "Stapling disabled"
fi

if [ "$COMPRESS_INPUT" != "false" ]; then
  log "Zipping $BUILD_NAME to $INPUT_FILE ..."
  (
    cd "$EXPLODED"
    ditto -c -k --sequesterRsrc --keepParent "$BUILD_NAME" "../$INPUT_FILE"
    log "Finished zipping"
  )
fi

log "Done"


text:
package org.jabe.neverland.autoinstall;

/**
 * Array Utils
 *

 *
{@link #isEmpty(Object[])} is null or its length is 0

 *
{@link #getLast(Object[], Object, Object, boolean)} get last element of the target element, before the first one
 * that match the target element front to back

 *
{@link #getNext(Object[], Object, Object, boolean)} get next element of the target element, after the first one
 * that match the target element front to back

 *
{@link #getLast(Object[], Object, boolean)}

 *
{@link #getLast(int[], int, int, boolean)}

 *
{@link #getLast(long[], long, long, boolean)}

 *
{@link #getNext(Object[], Object, boolean)}

 *
{@link #getNext(int[], int, int, boolean)}

 *
{@link #getNext(long[], long, long, boolean)}

 *

 *
 * @author Trinea 2011-10-24
 */
public class ArrayUtils {

    /**
     * is null or its length is 0
     *
     * @param <V>
     * @param sourceArray
     * @return
     */
    public static <V> boolean isEmpty(V[] sourceArray) {
        return (sourceArray == null || sourceArray.length == 0);
    }

    /**
     * get last element of the target element, before the first one that match the target element front to back
     *

     *
if array is empty, return defaultValue

     *
if target element is not exist in array, return defaultValue

     *
if target element exist in array and its index is not 0, return the last element

     *
if target element exist in array and its index is 0, return the last one in array if isCircle is true, else
     * return defaultValue

     *

     *
     * @param <V>
     * @param sourceArray
     * @param value value of target element
     * @param defaultValue default return value
     * @param isCircle whether is circle
     * @return
     */
    public static <V> V getLast(V[] sourceArray, V value, V defaultValue, boolean isCircle) {
        if (isEmpty(sourceArray)) {
            return defaultValue;
        }

        int currentPosition = -1;
        for (int i = 0; i < sourceArray.length; i++) {
            if (ObjectUtils.isEquals(value, sourceArray[i])) {
                currentPosition = i;
                break;
            }
        }
        if (currentPosition == -1) {
            return defaultValue;
        }

        if (currentPosition == 0) {
            return isCircle ? sourceArray[sourceArray.length - 1] : defaultValue;
        }
        return sourceArray[currentPosition - 1];
    }

    /**
     * get next element of the target element, after the first one that match the target element front to back
     *

     *
if array is empty, return defaultValue

     *
if target element is not exist in array, return defaultValue

     *
if target element exist in array and not the last one in array, return the next element

     *
if target element exist in array and the last one in array, return the first one in array if isCircle is
     * true, else return defaultValue

     *

     *
     * @param <V>
     * @param sourceArray
     * @param value value of target element
     * @param defaultValue default return value
     * @param isCircle whether is circle
     * @return
     */
    public static <V> V getNext(V[] sourceArray, V value, V defaultValue, boolean isCircle) {
        if (isEmpty(sourceArray)) {
            return defaultValue;
        }

        int currentPosition = -1;
        for (int i = 0; i < sourceArray.length; i++) {
            if (ObjectUtils.isEquals(value, sourceArray[i])) {
                currentPosition = i;
                break;
            }
        }
        if (currentPosition == -1) {
            return defaultValue;
        }

        if (currentPosition == sourceArray.length - 1) {
            return isCircle ? sourceArray[0] : defaultValue;
        }
        return sourceArray[currentPosition + 1];
    }

    /**
     * @see {@link ArrayUtils#getLast(Object[], Object, Object, boolean)} defaultValue is null
     */
    public static <V> V getLast(V[] sourceArray, V value, boolean isCircle) {
        return getLast(sourceArray, value, null, isCircle);
    }

    /**
     * @see {@link ArrayUtils#getNext(Object[], Object, Object, boolean)} defaultValue is null
     */
    public static <V> V getNext(V[] sourceArray, V value, boolean isCircle) {
        return getNext(sourceArray, value, null, isCircle);
    }

    /**
     * @see {@link ArrayUtils#getLast(Object[], Object, Object, boolean)} Object is Long
     */
    public static long getLast(long[] sourceArray, long value, long defaultValue, boolean isCircle) {
        if (sourceArray.length == 0) {
            throw new IllegalArgumentException("The length of source array must be greater than 0.");
        }

        Long[] array = ObjectUtils.transformLongArray(sourceArray);
        return getLast(array, value, defaultValue, isCircle);

    }

    /**
     * @see {@link ArrayUtils#getNext(Object[], Object, Object, boolean)} Object is Long
     */
    public static long getNext(long[] sourceArray, long value, long defaultValue, boolean isCircle) {
        if (sourceArray.length == 0) {
            throw new IllegalArgumentException("The length of source array must be greater than 0.");
        }

        Long[] array = ObjectUtils.transformLongArray(sourceArray);
        return getNext(array, value, defaultValue, isCircle);
    }

    /**
     * @see {@link ArrayUtils#getLast(Object[], Object, Object, boolean)} Object is Integer
     */
    public static int getLast(int[] sourceArray, int value, int defaultValue, boolean isCircle) {
        if (sourceArray.length == 0) {
            throw new IllegalArgumentException("The length of source array must be greater than 0.");
        }

        Integer[] array = ObjectUtils.transformIntArray(sourceArray);
        return getLast(array, value, defaultValue, isCircle);

    }

    /**
     * @see {@link ArrayUtils#getNext(Object[], Object, Object, boolean)} Object is Integer
     */
    public static int getNext(int[] sourceArray, int value, int defaultValue, boolean isCircle) {
        if (sourceArray.length == 0) {
            throw new IllegalArgumentException("The length of source array must be greater than 0.");
        }

        Integer[] array = ObjectUtils.transformIntArray(sourceArray);
        return getNext(array, value, defaultValue, isCircle);
    }
}


text:
llvm-scripts
============

scripts I use for building/testing llvm


text:
package net.jaggs.tinted.views;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;

import static net.jaggs.tinted.views.TintedViewUtils.*;

public class BrandedImageView extends TintedImageView {

	public BrandedImageView(Context context) {
		super(context);
		postConstruct();
	}

	public BrandedImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		postConstruct();
	}

	public BrandedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		postConstruct();
	}

	@TargetApi(Build.VERSION_CODES.LOLLIPOP)
	public BrandedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		postConstruct();
	}

	private void postConstruct() {
		if (getTintColor() == DEFAULT_TINT(getContext())) {
			setTintColor(BRAND_TINT(getContext()));
		}
		if (getHighlightTintColor() == DEFAULT_HIGHLIGHT_TINT(getContext())) {
			setHighlightTintColor(BRAND_HIGHLIGHT_TINT(getContext()));
		}
	}
}


text:
if [ $# -ne 3 ]; then
    echo "usage:"
    echo "  $0 <user email> <conv key> <tagpool:tagname>"
    exit 1
fi

email_address="$1"
conv="CONVERSATION:sequential_send:$2"
tag="TRANSPORT_TAG:$3"

. $(dirname $0)/mangle_routing_table_utils.sh

assert_routing_exists "$tag"

mrt --add $conv default $tag default


text:
"""
Provides an implementation of a rectangular simulation area in the
two-dimensional space.
"""

from sim2net.area._area import Area
from sim2net.utility.validation import check_argument_type

__docformat__ = 'reStructuredText'

class Rectangle(Area):
    """
    This class implements a rectangular simulation area of the given size in
    the two-dimensional space with the origin in (0, 0).
    """

    def __init__(self, width, height):
        """
        *Parameters*:
            - **width** (`float`): a width of the rectangular simulation area
              (along the horizontal x-axis),
            - **height** (`float`): a height of the rectangular simulation area
              (along the vertical y-axis).

        *Raises*:
            - **ValueError**: raised when a given value of either **width** or
              **height** parameter is equal to or less than 0.
        """
        super(Rectangle, self).__init__(Rectangle.__name__)
        check_argument_type(Rectangle.__name__, 'width', float, width,
                            self.logger)
        if width <= 0:
            raise ValueError('Parameter "width": the width of a simulation'
                             ' area cannot be equal to or less than 0, but'
                             ' %d given!' % float(width))
        self.__width = float(width)
        check_argument_type(Rectangle.__name__, 'height', float, height,
                            self.logger)
        if height <= 0:
            raise ValueError('Parameter "height": the height of a simulation'
                             ' area cannot be equal to or less than 0, but'
                             ' %d given!' % float(height))
        self.__height = float(height)

    @property
    def height(self):
        """
        (*Property*)  A height of the simulation area of type `float`.
        """
        return self.__height

    @property
    def width(self):
        """
        (*Property*)  A width of the simulation area of type `float`.
        """
        return self.__width

    def within(self, horizontal_coordinate, vertical_coordinate):
        """
        Tests whether the given coordinates are within the simulation area.

        *Parameters*:
            - **horizontal_coordinate** (`float`): a horizontal (x-axis)
              coordinate;
            - **vertical_coordinate** (`float`): a vertical (y-axis)
              coordinate.

        *Returns*:
            (`bool`) `True` if the given coordinates are within the rectangular
            simulation area, or `False` otherwise.
        """
        if horizontal_coordinate < 0.0 or vertical_coordinate < 0.0:
            return False
        if horizontal_coordinate <= self.__width \
                and vertical_coordinate <= self.__height:
            return True
        return False

    def get_area(self):
        """
        Creates a dictionary that stores information about the simulation area.

        *Returns*:
            A dictionary that stores information about the simulation area;
            it has the following fields:

                - 'area name': a name of the simulation area of type `str`,
                - 'width': a width of the simulation area of type `float`,
                - 'height': a height of the simulation area of type `float`.
        """
        return {'area name': self.__class__.__name__.lower(),
                'width': self.__width,
                'height': self.__height}


text:
#include "gm.h"
#include "SkCanvas.h"

static void test_nulldev(SkCanvas* canvas) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 30, 30);
    // notice: no pixels mom! be sure we don't crash
    // https://code.google.com/p/chromium/issues/detail?id=352616
    SkCanvas c(bm);

    SkBitmap src;
    src.allocN32Pixels(10, 10);
    src.eraseColor(SK_ColorRED);

    // ensure we don't crash
    c.writePixels(src, 0, 0);
}

static void draw_text_stroked(SkCanvas* canvas, const SkPaint& paint) {
    SkPaint p(paint);
    SkPoint loc = { 20, 450 };

    canvas->drawText("P", 1, loc.fX, loc.fY - 225, p);
    canvas->drawPosText("P", 1, &loc, p);

    p.setColor(SK_ColorRED);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(10);

    canvas->drawText("P", 1, loc.fX, loc.fY - 225, p);
    canvas->drawPosText("P", 1, &loc, p);
}

class StrokeTextGM : public skiagm::GM {
    // Skia has a threshold above which it draws text via paths instead of using scalercontext
    // and caching the glyph. This GM wants to ensure that we draw stroking correctly on both
    // sides of this threshold.
    enum {
        kBelowThreshold_TextSize = 255,
        kAboveThreshold_TextSize = 257
    };
public:
    StrokeTextGM() {}

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("stroketext");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        if (true) { test_nulldev(canvas); }
        SkPaint paint;
        paint.setAntiAlias(true);

        paint.setTextSize(kBelowThreshold_TextSize);
        draw_text_stroked(canvas, paint);

        canvas->translate(200, 0);
        paint.setTextSize(kAboveThreshold_TextSize);
        draw_text_stroked(canvas, paint);
    }

private:
    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW(StrokeTextGM); )


text:
namespace syncer {
#define ENUM_CASE(x) case x: return #x; break;

const char* GetSyncErrorTypeString(SyncProtocolErrorType type) {
  switch (type) {
    ENUM_CASE(SYNC_SUCCESS);
    ENUM_CASE(NOT_MY_BIRTHDAY);
    ENUM_CASE(THROTTLED);
    ENUM_CASE(CLEAR_PENDING);
    ENUM_CASE(TRANSIENT_ERROR);
    ENUM_CASE(NON_RETRIABLE_ERROR);
    ENUM_CASE(MIGRATION_DONE);
    ENUM_CASE(INVALID_CREDENTIAL);
    ENUM_CASE(DISABLED_BY_ADMIN);
    ENUM_CASE(USER_ROLLBACK);
    ENUM_CASE(UNKNOWN_ERROR);
  }
  NOTREACHED();
  return "";
}

const char* GetClientActionString(ClientAction action) {
  switch (action) {
    ENUM_CASE(UPGRADE_CLIENT);
    ENUM_CASE(CLEAR_USER_DATA_AND_RESYNC);
    ENUM_CASE(ENABLE_SYNC_ON_ACCOUNT);
    ENUM_CASE(STOP_AND_RESTART_SYNC);
    ENUM_CASE(DISABLE_SYNC_ON_CLIENT);
    ENUM_CASE(STOP_SYNC_FOR_DISABLED_ACCOUNT);
    ENUM_CASE(DISABLE_SYNC_AND_ROLLBACK);
    ENUM_CASE(ROLLBACK_DONE);
    ENUM_CASE(UNKNOWN_ACTION);
  }
  NOTREACHED();
  return "";
}

SyncProtocolError::SyncProtocolError()
    : error_type(UNKNOWN_ERROR),
      action(UNKNOWN_ACTION) {
}

SyncProtocolError::~SyncProtocolError() {
}

base::DictionaryValue* SyncProtocolError::ToValue() const {
  base::DictionaryValue* value = new base::DictionaryValue();
  value->SetString("ErrorType",
                   GetSyncErrorTypeString(error_type));
  value->SetString("ErrorDescription", error_description);
  value->SetString("url", url);
  value->SetString("action", GetClientActionString(action));
  return value;
}

}  // namespace syncer


text:
/**
 * @jest-environment jsdom
 */
/** @jsx h */

import algoliasearchHelper from 'algoliasearch-helper';
import { fireEvent } from '@testing-library/preact';
import instantsearch from '../../../index.es';
import { createSearchClient } from '@instantsearch/mocks/createSearchClient';
import { wait } from '@instantsearch/testutils/wait';
import answers from '../answers';
import searchBox from '../../search-box/search-box';
import { createInitOptions } from '../../../../test/createWidget';

describe('answers', () => {
  describe('Usage', () => {
    it('throws without `container`', () => {
      expect(() => {
        // @ts-expect-error
        answers({});
      }).toThrowErrorMatchingInlineSnapshot(`
"The \`container\` option is required.

See documentation: https://www.algolia.com/doc/api-reference/widgets/answers/js/"
`);
    });

    it('throws without `queryLanguages`', () => {
      const container = document.createElement('div');
      expect(() => {
        // @ts-expect-error
        answers({ container });
      }).toThrowErrorMatchingInlineSnapshot(`
"The \`queryLanguages\` expects an array of strings.

See documentation: https://www.algolia.com/doc/api-reference/widgets/answers/js/#connector"
`);
    });

    it('throws when searchClient does not support findAnswers', () => {
      const container = document.createElement('div');
      const searchClient = createSearchClient({
        // @ts-ignore-next-line
        initIndex() {
          return {};
        },
      });
      const helper = algoliasearchHelper(searchClient, '', {});
      const search = instantsearch({
        indexName: 'instant_search',
        searchClient,
      });
      search.helper = helper;
      const widget = answers({
        container,
        queryLanguages: ['en'],
        attributesForPrediction: ['description'],
      });
      expect(() => {
        widget.init!(
          createInitOptions({
            state: helper.state,
            helper,
            instantSearchInstance: search,
          })
        );
      }).toThrowErrorMatchingInlineSnapshot(`
"\`algoliasearch\` >= 4.8.0 required.

See documentation: https://www.algolia.com/doc/api-reference/widgets/answers/js/#connector"
`);
    });
  });

  describe('render', () => {
    it('renders with empty state', async () => {
      const container = document.createElement('div');
      const search = instantsearch({
        indexName: 'instant_search',
        searchClient: createSearchClient({
          // @ts-ignore-next-line
          initIndex() {
            return {
              findAnswers: () => Promise.resolve({ hits: [] }),
            };
          },
        }),
      });
      search.addWidgets([
        answers({
          container,
          queryLanguages: ['en'],
          attributesForPrediction: ['description'],
        }),
      ]);
      search.start();
      await wait(0);
      expect(container.innerHTML).toMatchInlineSnapshot(
        `"<div class=\\"ais-Answers ais-Answers--empty\\"><div class=\\"ais-Answers-header\\"></div><ul class=\\"ais-Answers-list\\"></ul></div>"`
      );
    });

    it('renders the answers', async () => {
      const answersContainer = document.createElement('div');
      const searchBoxContainer = document.createElement('div');
      const search = instantsearch({
        indexName: 'instant_search',
        searchClient: createSearchClient({
          // @ts-ignore-next-line
          initIndex() {
            return {
              findAnswers: () => {
                return Promise.resolve({ hits: [{ title: 'Hello' }] });
              },
            };
          },
        }),
      });
      search.addWidgets([
        answers({
          container: answersContainer,
          queryLanguages: ['en'],
          attributesForPrediction: ['description'],
          renderDebounceTime: 10,
          searchDebounceTime: 10,
          cssClasses: {
            root: 'root',
            loader: 'loader',
            emptyRoot: 'empty',
            item: 'item',
          },
          templates: {
            loader: 'loading...',
            item: (hit) => `title: ${hit.title}`,
          },
        }),
        searchBox({
          container: searchBoxContainer,
        }),
      ]);
      search.start();
      await wait(0);

      fireEvent.input(searchBoxContainer.querySelector('input')!, {
        target: { value: 'a' },
      });

      await wait(0);
      expect(answersContainer.querySelector('.loader')!.innerHTML).toEqual(
        'loading...'
      );
      expect(answersContainer.querySelector('.root')).toHaveClass('empty');

      await wait(100);

      // debounced render
      expect(answersContainer.querySelector('.root')).not.toHaveClass('empty');
      expect(answersContainer.querySelectorAll('.item').length).toEqual(1);
      expect(answersContainer.querySelector('.item')!.innerHTML).toEqual(
        'title: Hello'
      );
    });
  });
});


text:
@import Foundation;

@class SPTDataLoaderFactory;
@class SPTDataLoaderRateLimiter;
@class SPTDataLoaderResolver;

@protocol SPTDataLoaderConsumptionObserver;

/**
 * The service used for creating data loader factories and providing application wide rate limiting to services
 */
@interface SPTDataLoaderService : NSObject

/**
 * Whether all certificates are allowed (e.g. broken certificates don't cause closed connections)
 * @discussion By default this is NO. You should only turn this on if you are certain it will not be on in release
 * builds.
 * @warning This will trigger an assert if all certificates are allowed on release builds.
 */
@property (nonatomic, assign, readwrite, getter = areAllCertificatesAllowed) BOOL allCertificatesAllowed;

/**
 * Class constructor
 * @param userAgent The user agent to report as when making HTTP requests
 * @param rateLimiter The limiter for limiting requests per second on a per service basis
 * @param resolver The resolver for rerouting requests to different IP addresses
 * @param customURLProtocolClasses Array of NSURLProtocol Class objects that you want
 *                                 to use for this DataLoaderService. May be nil.
 */
+ (instancetype)dataLoaderServiceWithUserAgent:(NSString *)userAgent
                                   rateLimiter:(SPTDataLoaderRateLimiter *)rateLimiter
                                      resolver:(SPTDataLoaderResolver *)resolver
                      customURLProtocolClasses:(NSArray *)customURLProtocolClasses;

/**
 * Creates a data loader factory
 * @param authorisers An NSArray of SPTDataLoaderAuthoriser objects for supporting different forms of authorisation
 */
- (SPTDataLoaderFactory *)createDataLoaderFactoryWithAuthorisers:(NSArray *)authorisers;
/**
 * Adds a consumption observer
 * @param consumptionObserver The consumption observer to add to the service
 * @param queue The queue to call the consumption observer on
 * @warning This will have a weak reference to the consumption observer
 */
- (void)addConsumptionObserver:(id<SPTDataLoaderConsumptionObserver>)consumptionObserver on:(dispatch_queue_t)queue;
/**
 * Removes a consumption observer
 * @param consumptionObserver The consumption observer to remove from the service
 */
- (void)removeConsumptionObserver:(id<SPTDataLoaderConsumptionObserver>)consumptionObserver;

@end


text:
package io.debezium.pipeline.source.snapshot.incremental;

import java.util.List;
import java.util.Map;
import java.util.Optional;

public interface IncrementalSnapshotContext<T> {

    T currentDataCollectionId();

    T nextDataCollection();

    List<T> addDataCollectionNamesToSnapshot(List<String> dataCollectionIds);

    int tablesToBeSnapshottedCount();

    boolean openWindow(String id);

    boolean closeWindow(String id);

    boolean isNonInitialChunk();

    boolean snapshotRunning();

    void startNewChunk();

    void nextChunkPosition(Object[] lastKey);

    String currentChunkId();

    Object[] chunkEndPosititon();

    void sendEvent(Object[] keyFromRow);

    void maximumKey(Object[] key);

    Optional<Object[]> maximumKey();

    boolean deduplicationNeeded();

    Map<String, Object> store(Map<String, Object> offset);

    void revertChunk();
}


text:
package com.intel.analytics.bigdl.dllib.keras.layers

import com.intel.analytics.bigdl.dllib.nn.abstractnn.AbstractModule
import com.intel.analytics.bigdl.dllib.nn.internal.KerasLayer
import com.intel.analytics.bigdl.dllib.tensor.Tensor
import com.intel.analytics.bigdl.dllib.tensor.TensorNumericMath.TensorNumeric
import com.intel.analytics.bigdl.dllib.utils.{Log4Error, Shape}
import com.intel.analytics.bigdl.dllib.keras.Net
import com.intel.analytics.bigdl.dllib.keras.layers.utils.KerasUtils

import scala.reflect.ClassTag

/**
 * Select an index of the input in the given dim and return the subset part.
 * The batch dimension needs to be unchanged.
 * For example, if input is:
 * 1 2 3
 * 4 5 6
 * Select(1, 1) will give output [2 5]
 * Select(1, -1) will give output [3 6]
 *
 * When you use this layer as the first layer of a model, you need to provide the argument
 * inputShape (a Single Shape, does not include the batch dimension).
 *
 * Remark: This layer is from Torch and wrapped in Keras style.
 *
 * @param dim The dimension to select. 0-based index. Cannot select the batch dimension.
 *            -1 means the last dimension of the input.
 * @param index The index of the dimension to be selected. 0-based index.
 *              -1 means the last dimension of the input.
 * @param inputShape A Single Shape, does not include the batch dimension.
 * @tparam T Numeric type of parameter(e.g. weight, bias). Only support float/double now.
 */
class Select[T: ClassTag](
    val dim: Int,
    val index: Int,
    val inputShape: Shape = null)(implicit ev: TensorNumeric[T])
  extends KerasLayer[Tensor[T], Tensor[T], T](KerasUtils.addBatch(inputShape)) with Net {

  private def getPositiveDimAndIndex(inputShape: Shape): (Int, Int) = {
    val input = inputShape.toSingle().toArray
    Log4Error.invalidInputError(input.length >= 2,
      s"Select requires >= 2D input, but got input dim ${input.length}")
    val positiveDim = if (dim < 0) dim + input.length else dim
    Log4Error.invalidInputError(positiveDim != 0, "Cannot select the batch dimension")
    Log4Error.invalidInputError(positiveDim > 0 && positiveDim <= input.length - 1,
      s"Invalid select dim: $dim, dim should be within range (0, ${input.length - 1}]")
    val positiveIndex = if (index < 0) index + input(positiveDim) else index
    Log4Error.invalidInputError(positiveIndex >= 0 && positiveIndex <= input(positiveDim) - 1,
      s"Invalid select index for dim $dim: $index, " +
        s"index should be within range [0, ${input(positiveDim) - 1}]")
    (positiveDim, positiveIndex)
  }

  override def computeOutputShape(inputShape: Shape): Shape = {
    val input = inputShape.toSingle().toArray.toBuffer
    input.remove(getPositiveDimAndIndex(inputShape)._1)
    Shape(input.toArray)
  }

  override def doBuild(inputShape: Shape): AbstractModule[Tensor[T], Tensor[T], T] = {
    val (positiveDim, positiveIndex) = getPositiveDimAndIndex(inputShape)
    val layer = com.intel.analytics.bigdl.dllib.nn.Select(positiveDim + 1, positiveIndex + 1)
    layer.asInstanceOf[AbstractModule[Tensor[T], Tensor[T], T]]
  }

  override private[bigdl] def toKeras2(): String = {
    val params = Net.inputShapeToString(inputShape) ++
      Net.param(getName()) ++
      Net.param(dim, "dim")
    Net.kerasDef(this, params)
  }
}

object Select {
  def apply[@specialized(Float, Double) T: ClassTag](
    dim: Int,
    index: Int,
    inputShape: Shape = null)(implicit ev: TensorNumeric[T]): Select[T] = {
    new Select[T](dim, index, inputShape)
  }
}


text:
package com.tle.jpfclasspath.model;

import java.util.HashSet;
import java.util.Set;

public class PluginUpdateTracker {
  private Set<IPluginModel> changes = new HashSet<>();

  public void addChange(IPluginModel change) {
    changes.add(change);
  }

  public Set<IPluginModel> getChanges() {
    return changes;
  }
}


text:
require 'test_helper'

describe Lotus::Validations do
  describe 'format' do
    it "is valid if it doesn't have attributes" do
      validator = FormatValidatorTest.new({})

      validator.valid?.must_equal true
      validator.errors.must_be_empty
    end

    it "is valid if it respects given formats" do
      validator = FormatValidatorTest.new({name: 'Luca', age: '32'})

      validator.valid?.must_equal true
      validator.errors.must_be_empty
    end

    it "isn't valid if one doesn't respect given formats" do
      validator = FormatValidatorTest.new({name: 'Luca', age: 'thirtytwo'})

      validator.valid?.must_equal false
      error = validator.errors.for(:age)
      error.must_include Lotus::Validations::Error.new(:age, :format, /\A[0-9]+\z/, 'thirtytwo')
    end
  end
end


text:
<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class Olhos_model extends CI_Model {

    public function __construct() {
        parent::__construct();
    }

    public function get_olhos(){
        $rs = $this->db->get_where("cor_olhos", array('ativo' => 1))->result();

        return $rs;
    }
}


text:
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/

#pragma once

/***
  This file is part of systemd.

  Copyright 2010 Lennart Poettering

  systemd is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.

  systemd is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/

#include <stdarg.h>
#include <stdbool.h>

#include "macro.h"

char *strv_find(char **l, const char *name) _pure_;
char *strv_find_prefix(char **l, const char *name) _pure_;

void strv_free(char **l);
static inline void strv_freep(char ***l) {
        strv_free(*l);
}

#define _cleanup_strv_free_ _cleanup_(strv_freep)

char **strv_copy(char * const *l);
unsigned strv_length(char * const *l) _pure_;

char **strv_merge(char **a, char **b);
char **strv_merge_concat(char **a, char **b, const char *suffix);
char **strv_append(char **l, const char *s);
int strv_extend(char ***l, const char *value);
int strv_push(char ***l, char *value);

char **strv_remove(char **l, const char *s);
char **strv_remove_prefix(char **l, const char *s);
char **strv_uniq(char **l);

#define strv_contains(l, s) (!!strv_find((l), (s)))

char **strv_new(const char *x, ...) _sentinel_;
char **strv_new_ap(const char *x, va_list ap);

static inline const char* STRV_IFNOTNULL(const char *x) {
        return x ? x : (const char *) -1;
}

static inline bool strv_isempty(char * const *l) {
        return !l || !*l;
}

char **strv_split(const char *s, const char *separator);
char **strv_split_quoted(const char *s);
char **strv_split_newlines(const char *s);

char *strv_join(char **l, const char *separator);

char **strv_parse_nulstr(const char *s, size_t l);
char **strv_split_nulstr(const char *s);

bool strv_overlap(char **a, char **b) _pure_;

#define STRV_FOREACH(s, l)                      \
        for ((s) = (l); (s) && *(s); (s)++)

#define STRV_FOREACH_BACKWARDS(s, l)            \
        for (; (l) && ((s) >= (l)); (s)--)

#define STRV_FOREACH_PAIR(x, y, l)               \
        for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1))

char **strv_sort(char **l);
void strv_print(char **l);


text:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ChangeListManager">
    <list default="true" id="8dad84b5-c1d8-4b37-a323-ff23c7e43710" name="Default" comment="" />
    <ignored path="b2b-email-course.iws" />
    <ignored path=".idea/workspace.xml" />
    <file path="/index.html" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395878804496" ignored="false" />
    <file path="/dummy.xml" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395878804496" ignored="false" />
    <file path="/style.css" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395879370888" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-webinar-signup-desk/index.html" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395878809164" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-webinar-signup-desk/.idea/workspace.xml" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395879565674" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-webinar-signup-desk/css/style.css" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395879371361" ignored="false" />
    <file path="/Dummy.txt" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395786630992" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-ebook-download/index.html" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395793346845" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-ebook-download/css/style.css" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395793762080" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-webinar-signup-host/index.html" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395878028230" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-webinar-signup-host/.idea/workspace.xml" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395879371901" ignored="false" />
    <file path="$PROJECT_DIR$/../b2b-webinar-signup-host/css/style.css" changelist="8dad84b5-c1d8-4b37-a323-ff23c7e43710" time="1395878708343" ignored="false" />
    <option name="TRACKING_ENABLED" value="true" />
    <option name="SHOW_DIALOG" value="false" />
    <option name="HIGHLIGHT_CONFLICTS" value="true" />
    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
    <option name="LAST_RESOLUTION" value="IGNORE" />
  </component>
  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
  <component name="CreatePatchCommitExecutor">
    <option name="PATCH_PATH" value="" />
  </component>
  <component name="DaemonCodeAnalyzer">
    <disable_hints />
  </component>
  <component name="DebuggerManager">
    <ui_properties default_suspend_policy="SuspendAll" default_condition_enabled="true" />
    <breakpoint_any default_suspend_policy="SuspendAll" default_condition_enabled="true">
      <breakpoint>
        <option name="NOTIFY_CAUGHT" value="true" />
        <option name="NOTIFY_UNCAUGHT" value="true" />
        <option name="ENABLED" value="false" />
        <option name="LOG_ENABLED" value="false" />
        <option name="LOG_EXPRESSION_ENABLED" value="false" />
        <option name="REMOVE_AFTER_HIT" value="false" />
        <option name="SUSPEND_POLICY" value="SuspendAll" />
        <option name="SUSPEND" value="true" />
        <option name="COUNT_FILTER_ENABLED" value="false" />
        <option name="COUNT_FILTER" value="0" />
        <option name="CONDITION_ENABLED" value="true" />
        <option name="CLASS_FILTERS_ENABLED" value="false" />
        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
        <option name="CONDITION" value="" />
        <option name="LOG_MESSAGE" value="" />
      </breakpoint>
      <breakpoint>
        <option name="NOTIFY_CAUGHT" value="true" />
        <option name="NOTIFY_UNCAUGHT" value="true" />
        <option name="ENABLED" value="false" />
        <option name="LOG_ENABLED" value="false" />
        <option name="LOG_EXPRESSION_ENABLED" value="false" />
        <option name="REMOVE_AFTER_HIT" value="false" />
        <option name="SUSPEND_POLICY" value="SuspendAll" />
        <option name="SUSPEND" value="true" />
        <option name="COUNT_FILTER_ENABLED" value="false" />
        <option name="COUNT_FILTER" value="0" />
        <option name="CONDITION_ENABLED" value="true" />
        <option name="CLASS_FILTERS_ENABLED" value="false" />
        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
        <option name="CONDITION" value="" />
        <option name="LOG_MESSAGE" value="" />
      </breakpoint>
    </breakpoint_any>
    <breakpoint_rules />
    <ui_properties />
  </component>
  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
  <component name="FavoritesManager">
    <favorites_list name="b2b-email-course" />
  </component>
  <component name="FileEditorManager">
    <leaf>
      <file leaf-file-name="index.html" pinned="false" current="true" current-in-tab="true">
        <entry file="file://$PROJECT_DIR$/index.html">
          <provider selected="true" editor-type-id="text-editor">
            <state line="65" column="44" selection-start="2190" selection-end="2192" vertical-scroll-proportion="0.33206108">
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="style.css" pinned="false" current="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/css/style.css">
          <provider selected="true" editor-type-id="text-editor">
            <state line="102" column="22" selection-start="1898" selection-end="1898" vertical-scroll-proportion="0.0">
              <folding />
            </state>
          </provider>
        </entry>
      </file>
    </leaf>
  </component>
  <component name="FindManager">
    <FindUsagesManager>
      <setting name="OPEN_NEW_TAB" value="false" />
    </FindUsagesManager>
  </component>
  <component name="IdeDocumentHistory">
    <option name="changedFiles">
      <list>
        <option value="$PROJECT_DIR$/css/style.css" />
        <option value="$PROJECT_DIR$/index.html" />
      </list>
    </option>
  </component>
  <component name="ProjectFrameBounds">
    <option name="x" value="308" />
    <option name="y" value="22" />
    <option name="width" value="1280" />
    <option name="height" value="732" />
  </component>
  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
    <OptionsSetting value="true" id="Add" />
    <OptionsSetting value="true" id="Remove" />
    <OptionsSetting value="true" id="Checkout" />
    <OptionsSetting value="true" id="Update" />
    <OptionsSetting value="true" id="Status" />
    <OptionsSetting value="true" id="Edit" />
    <ConfirmationsSetting value="0" id="Add" />
    <ConfirmationsSetting value="0" id="Remove" />
  </component>
  <component name="ProjectReloadState">
    <option name="STATE" value="0" />
  </component>
  <component name="ProjectView">
    <navigator currentView="ProjectPane" proportions="" version="1" splitterProportion="0.5">
      <flattenPackages />
      <showMembers />
      <showModules />
      <showLibraryContents />
      <hideEmptyPackages />
      <abbreviatePackageNames />
      <autoscrollToSource />
      <autoscrollFromSource />
      <sortByType />
    </navigator>
    <panes>
      <pane id="ProjectPane">
        <subPane>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="b2b-email-course" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="b2b-email-course" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="b2b-email-course" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="b2b-email-course" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="b2b-email-course" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="css" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
        </subPane>
      </pane>
      <pane id="Scope" />
      <pane id="PackagesPane" />
    </panes>
  </component>
  <component name="PropertiesComponent">
    <property name="GoToFile.includeJavaFiles" value="false" />
    <property name="GoToClass.toSaveIncludeLibraries" value="false" />
    <property name="options.splitter.main.proportions" value="0.3" />
    <property name="WebServerToolWindowFactoryState" value="false" />
    <property name="MemberChooser.sorted" value="false" />
    <property name="options.lastSelected" value="Settings.JavaScript.Linters" />
    <property name="MemberChooser.showClasses" value="true" />
    <property name="GoToClass.includeLibraries" value="false" />
    <property name="MemberChooser.copyJavadoc" value="false" />
    <property name="options.splitter.details.proportions" value="0.2" />
    <property name="options.searchVisible" value="true" />
  </component>
  <component name="RunManager">
    <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
      <module name="" />
      <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m" />
      <option name="PROGRAM_PARAMETERS" />
      <method />
    </configuration>
    <configuration default="true" type="Remote" factoryName="Remote">
      <option name="USE_SOCKET_TRANSPORT" value="true" />
      <option name="SERVER_MODE" value="false" />
      <option name="SHMEM_ADDRESS" value="javadebug" />
      <option name="HOST" value="localhost" />
      <option name="PORT" value="5005" />
      <method />
    </configuration>
    <configuration default="true" type="Applet" factoryName="Applet">
      <module name="" />
      <option name="MAIN_CLASS_NAME" />
      <option name="HTML_FILE_NAME" />
      <option name="HTML_USED" value="false" />
      <option name="WIDTH" value="400" />
      <option name="HEIGHT" value="300" />
      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
      <option name="VM_PARAMETERS" />
      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
      <option name="ALTERNATIVE_JRE_PATH" />
      <method />
    </configuration>
    <configuration default="true" type="Application" factoryName="Application">
      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
      <option name="MAIN_CLASS_NAME" />
      <option name="VM_PARAMETERS" />
      <option name="PROGRAM_PARAMETERS" />
      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
      <option name="ALTERNATIVE_JRE_PATH" />
      <option name="ENABLE_SWING_INSPECTOR" value="false" />
      <option name="ENV_VARIABLES" />
      <option name="PASS_PARENT_ENVS" value="true" />
      <module name="" />
      <envs />
      <method />
    </configuration>
    <configuration default="true" type="JavascriptDebugSession" factoryName="Local" singleton="true">
      <JSDebuggerConfigurationSettings>
        <option name="engineId" value="embedded" />
        <option name="fileUrl" />
      </JSDebuggerConfigurationSettings>
      <method />
    </configuration>
    <list size="0" />
    <configuration name="<template>" type="JUnit" default="true" selected="false">
      <option name="MAIN_CLASS_NAME" />
      <option name="VM_PARAMETERS" value="-ea" />
      <option name="PARAMETERS" />
      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
    </configuration>
    <configuration name="<template>" type="TestNG" default="true" selected="false">
      <option name="MAIN_CLASS_NAME" />
      <option name="VM_PARAMETERS" value="-ea" />
      <option name="PARAMETERS" />
      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
    </configuration>
    <configuration name="<template>" type="WebApp" default="true" selected="false">
      <Host>localhost</Host>
      <Port>5050</Port>
    </configuration>
  </component>
  <component name="ShelveChangesManager" show_recycled="false" />
  <component name="TaskManager">
    <task active="true" id="Default" summary="Default task">
      <changelist id="8dad84b5-c1d8-4b37-a323-ff23c7e43710" name="Default" comment="" />
      <created>1395764913822</created>
      <updated>1395764913822</updated>
    </task>
    <servers />
  </component>
  <component name="ToolWindowManager">
    <frame x="308" y="22" width="1280" height="732" extended-state="0" />
    <editor active="true" />
    <layout>
      <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
      <window_info id="Regex Tester" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
      <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.38816854" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
    </layout>
  </component>
  <component name="VcsContentAnnotationSettings">
    <option name="myLimit" value="2678400000" />
  </component>
  <component name="VcsManagerConfiguration">
    <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
    <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
    <option name="CHECK_NEW_TODO" value="true" />
    <option name="myTodoPanelSettings">
      <value>
        <are-packages-shown value="false" />
        <are-modules-shown value="false" />
        <flatten-packages value="false" />
        <is-autoscroll-to-source value="false" />
      </value>
    </option>
    <option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
    <option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
    <option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
    <option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
    <option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
    <option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
    <option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false" />
    <option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
    <option name="SHOW_ONLY_CHANGED_IN_SELECTION_DIFF" value="true" />
    <option name="CHECK_COMMIT_MESSAGE_SPELLING" value="true" />
    <option name="DEFAULT_PATCH_EXTENSION" value="patch" />
    <option name="SHORT_DIFF_HORIZONTALLY" value="true" />
    <option name="SHORT_DIFF_EXTRA_LINES" value="2" />
    <option name="SOFT_WRAPS_IN_SHORT_DIFF" value="true" />
    <option name="INCLUDE_TEXT_INTO_PATCH" value="false" />
    <option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
    <option name="SHOW_FILE_HISTORY_DETAILS" value="true" />
    <option name="SHOW_VCS_ERROR_NOTIFICATIONS" value="true" />
    <option name="SHOW_DIRTY_RECURSIVELY" value="false" />
    <option name="LIMIT_HISTORY" value="true" />
    <option name="MAXIMUM_HISTORY_ROWS" value="1000" />
    <option name="UPDATE_FILTER_SCOPE_NAME" />
    <option name="USE_COMMIT_MESSAGE_MARGIN" value="false" />
    <option name="COMMIT_MESSAGE_MARGIN_SIZE" value="72" />
    <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="false" />
    <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
    <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="false" />
    <option name="LAST_COMMIT_MESSAGE" />
    <option name="MAKE_NEW_CHANGELIST_ACTIVE" value="false" />
    <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
    <option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
    <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
    <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
    <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
    <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
    <option name="ACTIVE_VCS_NAME" />
    <option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
    <option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
    <option name="UPDATE_FILTER_BY_SCOPE" value="false" />
    <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
    <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
  </component>
  <component name="XDebuggerManager">
    <breakpoint-manager />
  </component>
  <component name="editorHistoryManager">
    <entry file="file://$PROJECT_DIR$/index.html">
      <provider selected="true" editor-type-id="text-editor">
        <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/css/style.css">
      <provider selected="true" editor-type-id="text-editor">
        <state line="102" column="22" selection-start="1898" selection-end="1898" vertical-scroll-proportion="0.0">
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/index.html">
      <provider selected="true" editor-type-id="text-editor">
        <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/css/style.css">
      <provider selected="true" editor-type-id="text-editor">
        <state line="206" column="31" selection-start="3735" selection-end="3735" vertical-scroll-proportion="0.0">
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/images/ar0imc-email-envelope.png">
      <provider selected="true" editor-type-id="images">
        <state />
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/images/paper-bkg-top.original.png">
      <provider selected="true" editor-type-id="images">
        <state />
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/images/bkg-images.original.jpg">
      <provider selected="true" editor-type-id="images">
        <state />
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/css/style.css">
      <provider selected="true" editor-type-id="text-editor">
        <state line="102" column="22" selection-start="1898" selection-end="1898" vertical-scroll-proportion="0.0">
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/index.html">
      <provider selected="true" editor-type-id="text-editor">
        <state line="65" column="44" selection-start="2190" selection-end="2192" vertical-scroll-proportion="0.33206108">
          <folding />
        </state>
      </provider>
    </entry>
  </component>
</project>


text:
import os
import sys

NAME = 'ShirtsioAPI'
execfile('shirtsio/version.py')
DESCRIPTION = 'Shirts.io API for Python'

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

try:
    from distutils.command.build_py import build_py_2to3 as build_py
except ImportError:
    from distutils.command.build_py import build_py

path, script = os.path.split(sys.argv[0])
os.chdir(os.path.abspath(path))

requests = 'requests >= 0.8.8'
if sys.version_info < (2, 6):
    requests += ', < 0.10.1'
install_requires = [requests]

from shirtsio.version import VERSION

setup(name='shirtsio',
      version=VERSION,
      description=DESCRIPTION,
      author='shirtsio',
      author_email='support@shirts.io',
      url='https://github.com/ooshirts/shirtsio-python',
      packages=['shirtsio'],
      install_requires=install_requires,
      platforms='Any',
      classifiers=['Development Status :: 5 - Production/Stable',
                   'Intended Audience :: Developers',
                   'License :: OSI Approved :: MIT License',
                   'Operating System :: OS Independent',
                   'Programming Language :: Python',
                   'Topic :: Software Development',
                   'Topic :: Software Development :: Libraries',
                   'Topic :: Software Development :: Libraries :: Python Modules']
)


text:
[`figgy-pudding`](https://github.com/zkat/figgy-pudding) is a simple JavaScript library for managing and composing cascading options objects -- hiding what needs to be hidden from each layer, without having to do a lot of manual munging and passing of options.

## Install

`$ npm install figgy-pudding`

## Table of Contents

* [Example](#example)
* [Features](#features)
* [API](#api)
  * [`figgyPudding(spec)`](#figgy-pudding)
  * [`Opts(values)`](#opts)

### Example

```javascript
const puddin = require('figgyPudding')

const RequestOpts = puddin({
  follow: {
    default: true
  },
  streaming: {
    default: false
  },
  log: {
    default: require('npmlog')
  }
})

const MyAppOpts = puddin({
  log: {
    default: require('npmlog')
  },
  cache: {
    default: './cache'
  }
})

function start (opts) {
  opts = MyAppOpts(opts)
  initCache(opts.get('cache'))
  opts.get('streaming') // => undefined
  reqStuff('https://npm.im/figgy-pudding', opts)
}

function reqStuff (uri, opts) {
  opts = RequestOpts(opts)
  require('request').get(uri, opts) // can't see `cache`
}
```

### Features

* Hide options from layer that didn't ask for it
* Shared multi-layer options

### API

####  `> figgyPudding({ key: { default: val } | String }, [opts])`

Defines an Options constructor that can be used to collect only the needed
options.

An optional `default` property for specs can be used to specify default values
if nothing was passed in.

If the value for a spec is a string, it will be treated as an alias to that
other key.

##### Example

```javascript
const MyAppOpts = figgyPudding({
  lg: 'log',
  log: {
    default: () => require('npmlog')
  },
  cache: {}
})
```

####  `> Opts(...providers)`

Instantiates an options object defined by `figgyPudding()`, which uses
`providers`, in order, to find requested properties.

Each provider can be either a plain object, a `Map`-like object (that is, one
with a `.get()` method) or another figgyPudding `Opts` object.

When nesting `Opts` objects, their properties will not become available to the
new object, but any further nested `Opts` that reference that property _will_ be
able to read from their grandparent, as long as they define that key. Default
values for nested `Opts` parents will be used, if found.

##### Example

```javascript
const ReqOpts = figgyPudding({
  follow: {}
})

const opts = ReqOpts({
  follow: true,
  log: require('npmlog')
})

opts.get('follow') // => true
opts.get('log') // => Error: ReqOpts does not define `log`

const MoreOpts = figgyPudding({
  log: {}
})
MoreOpts(opts).log // => npmlog object (passed in from original plain obj)
MoreOpts(opts).get('follow') // => Error: MoreOpts does not define `follow`
```