text:
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x): val(x), left(NULL), right(NULL) {}
};

bool isvalidbst(TreeNode *root, int lower, int upper) {
    if (root == nullptr) return true;

    return root->val > lower && root->val < upper
           && isvalidbst(root->left, lower, root->val)
           && isvalidbst(root->right, root->val, upper);
}

bool isvalidbst(TreeNode *root) {
    return isvalidbst(root, INT_MIN, INT_MAX);
}

int main()
{
    return 0;
}

redpajama_set_name: RedPajamaGithub


text:
import createCircle from '../../../utils/create-circle';
import { module, test } from 'qunit';

module('Unit | Utility | create circle');

// Replace this with your real tests.
test('it works', function(assert) {
  var lat = 42.48019996901214;
  var lng = -71.10763549804688;
  var radius = 3947.236927961412;
  var result = createCircle(lat, lng, radius);

  assert.equal(result.length, 33);
  assert.ok(result[0].lat());
  assert.ok(result[0].lng());
});


text:
<!--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. -->

<wor:context-header
      xmlns:wor="http://airavata.apache.org/schemas/wec/2012/05">
    <wor:soa-service-eprs>
        <wor:gfac-url>gfacurl</wor:gfac-url>
        <wor:registry-url>registryurl</wor:registry-url>
    </wor:soa-service-eprs>
    <wor:workflow-monitoring-context>
        <wor:experiment-id>experimentid</wor:experiment-id>
        <wor:workflow-instance-id>workflowid</wor:workflow-instance-id>
        <wor:event-publish-epr>brokerurl</wor:event-publish-epr>
        <wor:msg-box-epr>msgBox</wor:msg-box-epr>
    </wor:workflow-monitoring-context>
    <wor:workflow-scheduling-context />
    <wor:security-context />
</wor:context-header>


text:
FROM ansible/ubuntu14.04-ansible:stable
# or, for example, FROM ansible/ubuntu14.04-ansible:stable

# Add playbooks to the Docker image
ADD ansible /srv/example/
WORKDIR /srv/example

# Run Ansible to configure the Docker image
RUN ansible-playbook site.yml -c local

# Other Dockerfile directives are still valid
EXPOSE 22 3000 80
ENTRYPOINT ["/usr/local/bin/apachectl", "-DFOREGROUND"]


text:
<?php
/**
 * Output stream applying a filter on data to write.
 *
 * @package     stubbles
 * @subpackage  streams_filter
 * @version     $Id: stubFilteredOutputStream.php 2324 2009-09-16 11:50:14Z mikey $
 */
stubClassLoader::load('net::stubbles::streams::stubAbstractDecoratedOutputStream',
                      'net::stubbles::streams::filter::stubStreamFilter'
);
/**
 * Output stream applying a filter on data to write.
 *
 * @package     stubbles
 * @subpackage  streams_filter
 */
class stubFilteredOutputStream extends stubAbstractDecoratedOutputStream
{
    /**
     * stream filter to be applied
     *
     * @var  stubStreamFilter
     */
    protected $streamFilter;

    /**
     * constructor
     *
     * @param  stubOutputStream  $outputStream  stream to apply filter onto
     * @param  stubStreamFilter  $streamFilter  stream filter to be applied
     */
    public function __construct(stubOutputStream $outputStream, stubStreamFilter $streamFilter)
    {
        parent::__construct($outputStream);
        $this->streamFilter = $streamFilter;
    }

    /**
     * writes given bytes
     *
     * @param   string  $bytes
     * @return  int     amount of written bytes
     */
    public function write($bytes)
    {
        if ($this->streamFilter->shouldFilter($bytes) === false) {
            return $this->outputStream->write($bytes);
        }

        return 0;
    }

    /**
     * writes given bytes and appends a line break
     *
     * @param   string  $bytes
     * @return  int     amount of written bytes excluding line break
     */
    public function writeLine($bytes)
    {
        if ($this->streamFilter->shouldFilter($bytes) === false) {
            return $this->outputStream->writeLine($bytes);
        }

        return 0;
    }
}
?>


text:
package de.frosner.broccoli.nomad.models

import play.api.libs.json.{JsPath, Reads}
import shapeless.tag
import shapeless.tag.@@
import squants.time.{Frequency, Megahertz}

/**
  * Statistics about CPU usage
  *
  * @param totalTicks The CPU ticks consumed
  */
final case class CpuStats(totalTicks: Frequency @@ CpuStats.TotalTicks)

object CpuStats {
  sealed trait TotalTicks

  implicit val cpuStatsReads: Reads[CpuStats] = for {
    ticks <- (JsPath \ "TotalTicks").read[Double].map(ticks => tag[CpuStats.TotalTicks](Megahertz(ticks)))
  } yield CpuStats(ticks)
}


text:
<?php

namespace Symfony\Component\Mime\Header;

/**
 * A Date MIME Header.
 *
 * @author Chris Corbyn
 */
final class DateHeader extends AbstractHeader
{
    private $dateTime;

    public function __construct(string $name, \DateTimeInterface $date)
    {
        parent::__construct($name);

        $this->setDateTime($date);
    }

    /**
     * @param \DateTimeInterface $body
     */
    public function setBody($body)
    {
        $this->setDateTime($body);
    }

    public function getBody(): \DateTimeImmutable
    {
        return $this->getDateTime();
    }

    public function getDateTime(): \DateTimeImmutable
    {
        return $this->dateTime;
    }

    /**
     * Set the date-time of the Date in this Header.
     *
     * If a DateTime instance is provided, it is converted to DateTimeImmutable.
     */
    public function setDateTime(\DateTimeInterface $dateTime)
    {
        if ($dateTime instanceof \DateTime) {
            $immutable = new \DateTimeImmutable('@'.$dateTime->getTimestamp());
            $dateTime = $immutable->setTimezone($dateTime->getTimezone());
        }
        $this->dateTime = $dateTime;
    }

    public function getBodyAsString(): string
    {
        return $this->dateTime->format(\DateTime::RFC2822);
    }
}


text:
namespace Microsoft.Azure.Management.Batch.Models
{
    using Newtonsoft.Json;
    using System.Linq;

    /// <summary>
    /// Settings which will be used by the data disks associated to Compute
    /// Nodes in the Pool. When using attached data disks, you need to mount
    /// and format the disks from within a VM to use them.
    /// </summary>
    public partial class DataDisk
    {
        /// <summary>
        /// Initializes a new instance of the DataDisk class.
        /// </summary>
        public DataDisk()
        {
            CustomInit();
        }

        /// <summary>
        /// Initializes a new instance of the DataDisk class.
        /// </summary>
        /// <param name="lun">The logical unit number.</param>
        /// <param name="diskSizeGB">The initial disk size in GB when creating
        /// new data disk.</param>
        /// <param name="caching">The type of caching to be enabled for the
        /// data disks.</param>
        /// <param name="storageAccountType">The storage account type to be
        /// used for the data disk.</param>
        public DataDisk(int lun, int diskSizeGB, CachingType? caching = default(CachingType?), StorageAccountType? storageAccountType = default(StorageAccountType?))
        {
            Lun = lun;
            Caching = caching;
            DiskSizeGB = diskSizeGB;
            StorageAccountType = storageAccountType;
            CustomInit();
        }

        /// <summary>
        /// An initialization method that performs custom operations like setting defaults
        /// </summary>
        partial void CustomInit();

        /// <summary>
        /// Gets or sets the logical unit number.
        /// </summary>
        /// <remarks>
        /// The lun is used to uniquely identify each data disk. If attaching
        /// multiple disks, each should have a distinct lun.
        /// </remarks>
        [JsonProperty(PropertyName = "lun")]
        public int Lun { get; set; }

        /// <summary>
        /// Gets or sets the type of caching to be enabled for the data disks.
        /// </summary>
        /// <remarks>
        /// Values are:
        ///
        /// none - The caching mode for the disk is not enabled.
        /// readOnly - The caching mode for the disk is read only.
        /// readWrite - The caching mode for the disk is read and write.
        ///
        /// The default value for caching is none. For information about the
        /// caching options see:
        /// https://blogs.msdn.microsoft.com/windowsazurestorage/2012/06/27/exploring-windows-azure-drives-disks-and-images/.
        /// Possible values include: 'None', 'ReadOnly', 'ReadWrite'
        /// </remarks>
        [JsonProperty(PropertyName = "caching")]
        public CachingType? Caching { get; set; }

        /// <summary>
        /// Gets or sets the initial disk size in GB when creating new data
        /// disk.
        /// </summary>
        [JsonProperty(PropertyName = "diskSizeGB")]
        public int DiskSizeGB { get; set; }

        /// <summary>
        /// Gets or sets the storage account type to be used for the data disk.
        /// </summary>
        /// <remarks>
        /// If omitted, the default is "Standard_LRS". Values are:
        ///
        /// Standard_LRS - The data disk should use standard locally redundant
        /// storage.
        /// Premium_LRS - The data disk should use premium locally redundant
        /// storage. Possible values include: 'Standard_LRS', 'Premium_LRS'
        /// </remarks>
        [JsonProperty(PropertyName = "storageAccountType")]
        public StorageAccountType? StorageAccountType { get; set; }

        /// <summary>
        /// Validate the object.
        /// </summary>
        /// <exception cref="Rest.ValidationException">
        /// Thrown if validation fails
        /// </exception>
        public virtual void Validate()
        {
        }
    }
}


text:
namespace UILibrary
{
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;

    [ToolboxBitmap(typeof(Button))]
    public class SkinButtom : Button
    {
        private Color _baseColor = Color.FromArgb(0x33, 0xa1, 0xe0);
        private ControlState _controlState;
        private int _imageWidth = 0x12;
        private RoundStyle _roundStyle;
        private Rectangle backrectangle = new Rectangle(10, 10, 10, 10);
        private IContainer components;
        private bool create;
        private Image downback;
        private DrawStyle drawType = DrawStyle.Draw;
        private Image mouseback;
        private Image normlback;
        private bool palace;
        private int radius = 8;
        private ControlState states;

        public SkinButtom()
        {
            this.Init();
            base.ResizeRedraw = true;
            this.BackColor = Color.Transparent;
        }

        private void CalculateRect(out Rectangle imageRect, out Rectangle textRect)
        {
            imageRect = Rectangle.Empty;
            textRect = Rectangle.Empty;
            if (base.Image == null)
            {
                textRect = new Rectangle(2, 0, base.Width - 4, base.Height);
            }
            else
            {
                switch (base.TextImageRelation)
                {
                    case TextImageRelation.Overlay:
                        imageRect = new Rectangle(2, (base.Height - this.ImageWidth) / 2, this.ImageWidth, this.ImageWidth);
                        textRect = new Rectangle(2, 0, base.Width - 4, base.Height);
                        break;

                    case TextImageRelation.ImageAboveText:
                        imageRect = new Rectangle((base.Width - this.ImageWidth) / 2, 2, this.ImageWidth, this.ImageWidth);
                        textRect = new Rectangle(2, imageRect.Bottom, base.Width, (base.Height - imageRect.Bottom) - 2);
                        break;

                    case TextImageRelation.TextAboveImage:
                        imageRect = new Rectangle((base.Width - this.ImageWidth) / 2, (base.Height - this.ImageWidth) - 2, this.ImageWidth, this.ImageWidth);
                        textRect = new Rectangle(0, 2, base.Width, (base.Height - imageRect.Y) - 2);
                        break;

                    case TextImageRelation.ImageBeforeText:
                        imageRect = new Rectangle(2, (base.Height - this.ImageWidth) / 2, this.ImageWidth, this.ImageWidth);
                        textRect = new Rectangle(imageRect.Right + 2, 0, (base.Width - imageRect.Right) - 4, base.Height);
                        break;

                    case TextImageRelation.TextBeforeImage:
                        imageRect = new Rectangle((base.Width - this.ImageWidth) - 2, (base.Height - this.ImageWidth) / 2, this.ImageWidth, this.ImageWidth);
                        textRect = new Rectangle(2, 0, imageRect.X - 2, base.Height);
                        break;
                }
                if (this.RightToLeft == RightToLeft.Yes)
                {
                    imageRect.X = base.Width - imageRect.Right;
                    textRect.X = base.Width - textRect.Right;
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void DrawGlass(Graphics g, RectangleF glassRect, int alphaCenter, int alphaSurround)
        {
            this.DrawGlass(g, glassRect, Color.White, alphaCenter, alphaSurround);
        }

        private void DrawGlass(Graphics g, RectangleF glassRect, Color glassColor, int alphaCenter, int alphaSurround)
        {
            using (GraphicsPath path = new GraphicsPath())
            {
                path.AddEllipse(glassRect);
                using (PathGradientBrush brush = new PathGradientBrush(path))
                {
                    brush.CenterColor = Color.FromArgb(alphaCenter, glassColor);
                    brush.SurroundColors = new Color[] { Color.FromArgb(alphaSurround, glassColor) };
                    brush.CenterPoint = new PointF(glassRect.X + (glassRect.Width / 2f), glassRect.Y + (glassRect.Height / 2f));
                    g.FillPath(brush, path);
                }
            }
        }

        private Color GetColor(Color colorBase, int a, int r, int g, int b)
        {
            int num = colorBase.A;
            int num2 = colorBase.R;
            int num3 = colorBase.G;
            int num4 = colorBase.B;
            if ((a + num) > 0xff)
            {
                a = 0xff;
            }
            else
            {
                a = Math.Max(a + num, 0);
            }
            if ((r + num2) > 0xff)
            {
                r = 0xff;
            }
            else
            {
                r = Math.Max(r + num2, 0);
            }
            if ((g + num3) > 0xff)
            {
                g = 0xff;
            }
            else
            {
                g = Math.Max(g + num3, 0);
            }
            if ((b + num4) > 0xff)
            {
                b = 0xff;
            }
            else
            {
                b = Math.Max(b + num4, 0);
            }
            return Color.FromArgb(a, r, g, b);
        }

        public static TextFormatFlags GetTextFormatFlags(ContentAlignment alignment, bool rightToleft)
        {
            TextFormatFlags flags = TextFormatFlags.SingleLine | TextFormatFlags.WordBreak;
            if (rightToleft)
            {
                flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
            }
            ContentAlignment alignment2 = alignment;
            if (alignment2 <= ContentAlignment.MiddleCenter)
            {
                switch (alignment2)
                {
                    case ContentAlignment.TopLeft:
                        return flags;

                    case ContentAlignment.TopCenter:
                        return (flags | TextFormatFlags.HorizontalCenter);

                    case (ContentAlignment.TopCenter | ContentAlignment.TopLeft):
                        return flags;

                    case ContentAlignment.TopRight:
                        return (flags | TextFormatFlags.Right);

                    case ContentAlignment.MiddleLeft:
                        return (flags | TextFormatFlags.VerticalCenter);

                    case ContentAlignment.MiddleCenter:
                        return (flags | (TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter));
                }
                return flags;
            }
            if (alignment2 <= ContentAlignment.BottomLeft)
            {
                switch (alignment2)
                {
                    case ContentAlignment.MiddleRight:
                        return (flags | (TextFormatFlags.VerticalCenter | TextFormatFlags.Right));

                    case ContentAlignment.BottomLeft:
                        return (flags | TextFormatFlags.Bottom);
                }
                return flags;
            }
            if (alignment2 != ContentAlignment.BottomCenter)
            {
                if (alignment2 != ContentAlignment.BottomRight)
                {
                    return flags;
                }
                return (flags | (TextFormatFlags.Bottom | TextFormatFlags.Right));
            }
            return (flags | (TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter));
        }

        public void Init()
        {
            base.SetStyle(ControlStyles.DoubleBuffer, true);
            base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.UserPaint, true);
            base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            base.SetStyle(ControlStyles.StandardDoubleClick, false);
            base.SetStyle(ControlStyles.Selectable, true);
            base.UpdateStyles();
        }

        private void InitializeComponent()
        {
            this.components = new Container();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.Invalidate();
            base.OnEnabledChanged(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                this._controlState = ControlState.Pressed;
                base.Invalidate();
                base.OnMouseDown(e);
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            this._controlState = ControlState.Hover;
            base.Invalidate();
            base.OnMouseEnter(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            this._controlState = ControlState.Normal;
            base.Invalidate();
            base.OnMouseLeave(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                this._controlState = ControlState.Hover;
                base.Invalidate();
            }
            base.OnMouseUp(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle rectangle;
            Rectangle rectangle2;
            Color controlDark;
            Color color2;
            base.OnPaint(e);
            base.OnPaintBackground(e);
            Graphics g = e.Graphics;
            Rectangle clientRectangle = base.ClientRectangle;
            this.CalculateRect(out rectangle, out rectangle2);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            Color innerBorderColor = Color.FromArgb(200, 0xff, 0xff, 0xff);
            Bitmap mouseBack = null;
            int num = 0;
            switch (this._controlState)
            {
                case ControlState.Hover:
                    mouseBack = (Bitmap) this.MouseBack;
                    controlDark = this.GetColor(this._baseColor, 0, -13, -8, -3);
                    color2 = this._baseColor;
                    break;

                case ControlState.Pressed:
                    mouseBack = (Bitmap) this.DownBack;
                    controlDark = this.GetColor(this._baseColor, 0, -35, -24, -9);
                    color2 = this._baseColor;
                    num = 1;
                    break;

                default:
                    mouseBack = (Bitmap) this.NormlBack;
                    controlDark = this._baseColor;
                    color2 = this._baseColor;
                    break;
            }
            if (!base.Enabled)
            {
                controlDark = SystemColors.ControlDark;
                color2 = SystemColors.ControlDark;
            }
            if ((mouseBack != null) && (this.DrawType == DrawStyle.Img))
            {
                CreateRegion(this, clientRectangle, this.Radius, this.RoundStyle);
                if (this.Create && (this._controlState != this.states))
                {
                    CreateControlRegion(this, mouseBack, 1);
                }
                if (this.Palace)
                {
                    ImageDrawRect.DrawRect(g, mouseBack, new Rectangle(clientRectangle.X, clientRectangle.Y, clientRectangle.Width, clientRectangle.Height), Rectangle.FromLTRB(this.BackRectangle.X, this.BackRectangle.Y, this.BackRectangle.Width, this.BackRectangle.Height), 1, 1);
                }
                else
                {
                    g.DrawImage(mouseBack, 0, 0, base.Width, base.Height);
                }
            }
            else if (this.DrawType == DrawStyle.Draw)
            {
                this.RenderBackgroundInternal(g, clientRectangle, controlDark, color2, innerBorderColor, this.RoundStyle, this.Radius, 0.35f, true, true, LinearGradientMode.Vertical);
            }
            Image image = null;
            Size empty = Size.Empty;
            if (base.Image != null)
            {
                if (string.IsNullOrEmpty(this.Text))
                {
                    image = base.Image;
                    empty = new Size(image.Width, image.Height);
                    clientRectangle.Inflate(-4, -4);
                    if ((empty.Width * empty.Height) != 0)
                    {
                        Rectangle withinThis = clientRectangle;
                        withinThis = ImageDrawRect.HAlignWithin(empty, withinThis, base.ImageAlign);
                        withinThis = ImageDrawRect.VAlignWithin(empty, withinThis, base.ImageAlign);
                        if (!base.Enabled)
                        {
                            ControlPaint.DrawImageDisabled(g, image, withinThis.Left, withinThis.Top, this.BackColor);
                        }
                        else
                        {
                            g.DrawImage(image, withinThis.Left + num, withinThis.Top + num, image.Width, image.Height);
                        }
                    }
                }
                else
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                    g.DrawImage(base.Image, rectangle, -num, -num, base.Image.Width, base.Image.Height, GraphicsUnit.Pixel);
                }
            }
            else if ((base.ImageList != null) && (base.ImageIndex != -1))
            {
                image = base.ImageList.Images[base.ImageIndex];
            }
            Color foreColor = base.Enabled ? this.ForeColor : SystemColors.ControlDark;
            TextRenderer.DrawText(g, this.Text, this.Font, rectangle2, foreColor, GetTextFormatFlags(this.TextAlign, this.RightToLeft == RightToLeft.Yes));
            this.states = this._controlState;
        }

        public void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor, RoundStyle style, int roundWidth, float basePosition, bool drawBorder, bool drawGlass, LinearGradientMode mode)
        {
            if (drawBorder)
            {
                rect.Width--;
                rect.Height--;
            }
            using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
            {
                Color[] colorArray = new Color[] { this.GetColor(baseColor, 0, 0x23, 0x18, 9), this.GetColor(baseColor, 0, 13, 8, 3), baseColor, this.GetColor(baseColor, 0, 0x44, 0x45, 0x36) };
                ColorBlend blend = new ColorBlend();
                float[] numArray = new float[4];
                numArray[1] = basePosition;
                numArray[2] = basePosition + 0.05f;
                numArray[3] = 1f;
                blend.Positions = numArray;
                blend.Colors = colorArray;
                brush.InterpolationColors = blend;
                if (style != RoundStyle.None)
                {
                    using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                    {
                        g.FillPath(brush, path);
                    }
                    if (baseColor.A > 80)
                    {
                        Rectangle rectangle = rect;
                        if (mode == LinearGradientMode.Vertical)
                        {
                            rectangle.Height = (int) (rectangle.Height * basePosition);
                        }
                        else
                        {
                            rectangle.Width = (int) (rect.Width * basePosition);
                        }
                        using (GraphicsPath path2 = GraphicsPathHelper.CreatePath(rectangle, roundWidth, RoundStyle.Top, false))
                        {
                            using (SolidBrush brush2 = new SolidBrush(Color.FromArgb(80, 0xff, 0xff, 0xff)))
                            {
                                g.FillPath(brush2, path2);
                            }
                        }
                    }
                    if (drawGlass)
                    {
                        RectangleF glassRect = rect;
                        if (mode == LinearGradientMode.Vertical)
                        {
                            glassRect.Y = rect.Y + (rect.Height * basePosition);
                            glassRect.Height = (rect.Height - (rect.Height * basePosition)) * 2f;
                        }
                        else
                        {
                            glassRect.X = rect.X + (rect.Width * basePosition);
                            glassRect.Width = (rect.Width - (rect.Width * basePosition)) * 2f;
                        }
                        this.DrawGlass(g, glassRect, 170, 0);
                    }
                    if (!drawBorder)
                    {
                        return;
                    }
                    using (GraphicsPath path3 = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                    {
                        using (Pen pen = new Pen(borderColor))
                        {
                            g.DrawPath(pen, path3);
                        }
                    }
                    rect.Inflate(-1, -1);
                    using (GraphicsPath path4 = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                    {
                        using (Pen pen2 = new Pen(innerBorderColor))
                        {
                            g.DrawPath(pen2, path4);
                        }
                        return;
                    }
                }
                g.FillRectangle(brush, rect);
                if (baseColor.A > 80)
                {
                    Rectangle rectangle2 = rect;
                    if (mode == LinearGradientMode.Vertical)
                    {
                        rectangle2.Height = (int) (rectangle2.Height * basePosition);
                    }
                    else
                    {
                        rectangle2.Width = (int) (rect.Width * basePosition);
                    }
                    using (SolidBrush brush3 = new SolidBrush(Color.FromArgb(80, 0xff, 0xff, 0xff)))
                    {
                        g.FillRectangle(brush3, rectangle2);
                    }
                }
                if (drawGlass)
                {
                    RectangleF ef2 = rect;
                    if (mode == LinearGradientMode.Vertical)
                    {
                        ef2.Y = rect.Y + (rect.Height * basePosition);
                        ef2.Height = (rect.Height - (rect.Height * basePosition)) * 2f;
                    }
                    else
                    {
                        ef2.X = rect.X + (rect.Width * basePosition);
                        ef2.Width = (rect.Width - (rect.Width * basePosition)) * 2f;
                    }
                    this.DrawGlass(g, ef2, 200, 0);
                }
                if (drawBorder)
                {
                    using (Pen pen3 = new Pen(borderColor))
                    {
                        g.DrawRectangle(pen3, rect);
                    }
                    rect.Inflate(-1, -1);
                    using (Pen pen4 = new Pen(innerBorderColor))
                    {
                        g.DrawRectangle(pen4, rect);
                    }
                }
            }
        }

        public static void CreateRegion(Control control, Rectangle bounds, int radius, RoundStyle roundStyle)
        {
            if (roundStyle != RoundStyle.None)
            {
                using (GraphicsPath path = GraphicsPathHelper.CreatePath(bounds, radius, roundStyle, true))
                {
                    Region region = new Region(path);
                    path.Widen(Pens.White);
                    region.Union(path);
                    control.Region = region;
                    return;
                }
            }
            if (control.Region != null)
            {
                control.Region = null;
            }
        }

        public static void CreateControlRegion(Control control, Bitmap bitmap, int Alpha)
        {
            if ((control != null) && (bitmap != null))
            {
                control.Width = bitmap.Width;
                control.Height = bitmap.Height;
                if (control is Form)
                {
                    Form form = (Form)control;
                    form.Width = control.Width;
                    form.Height = control.Height;
                    form.FormBorderStyle = FormBorderStyle.None;
                    form.BackgroundImage = bitmap;
                    GraphicsPath path = CalculateControlGraphicsPath(bitmap, Alpha);
                    form.Region = new Region(path);
                }
                else if (control is SkinButtom)
                {
                    SkinButtom buttom = (SkinButtom)control;
                    GraphicsPath path2 = CalculateControlGraphicsPath(bitmap, Alpha);
                    buttom.Region = new Region(path2);
                }
                //else if (control is SkinProgressBar)
                //{
                //    SkinProgressBar bar = (SkinProgressBar)control;
                //    GraphicsPath path3 = CalculateControlGraphicsPath(bitmap, Alpha);
                //    bar.Region = new Region(path3);
                //}
            }
        }

        public static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap, int Alpha)
        {
            GraphicsPath path = new GraphicsPath();
            int x = 0;
            for (int i = 0; i < bitmap.Height; i++)
            {
                x = 0;
                for (int j = 0; j < bitmap.Width; j++)
                {
                    if (bitmap.GetPixel(j, i).A < Alpha)
                    {
                        continue;
                    }
                    x = j;
                    int num4 = j;
                    num4 = x;
                    while (num4 < bitmap.Width)
                    {
                        if (bitmap.GetPixel(num4, i).A < Alpha)
                        {
                            break;
                        }
                        num4++;
                    }
                    path.AddRectangle(new Rectangle(x, i, num4 - x, 1));
                    j = num4;
                }
            }
            return path;
        }

        [Category("Skin"), DefaultValue(typeof(Rectangle), "10,10,10,10"), Description("九宫绘画区域")]
        public Rectangle BackRectangle
        {
            get
            {
                return this.backrectangle;
            }
            set
            {
                if (this.backrectangle != value)
                {
                    this.backrectangle = value;
                }
                base.Invalidate();
            }
        }

        [Category("Skin"), Description("非图片绘制时Bottom色调"), DefaultValue(typeof(Color), "51, 161, 224")]
        public Color BaseColor
        {
            get
            {
                return this._baseColor;
            }
            set
            {
                this._baseColor = value;
                base.Invalidate();
            }
        }

        [Description("控件状态")]
        public ControlState ControlState
        {
            get
            {
                return this._controlState;
            }
            set
            {
                if (this._controlState != value)
                {
                    this._controlState = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(bool), "false"), Description("是否开启:根据所绘图限制控件范围"), Category("Skin")]
        public bool Create
        {
            get
            {
                return this.create;
            }
            set
            {
                if (this.create != value)
                {
                    this.create = value;
                    base.Invalidate();
                }
            }
        }

        [Category("MouseDown"), Description("点击时背景")]
        public Image DownBack
        {
            get
            {
                return this.downback;
            }
            set
            {
                if (this.downback != value)
                {
                    this.downback = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(DrawStyle), "2"), Category("Skin"), Description("按钮的绘画模式")]
        public DrawStyle DrawType
        {
            get
            {
                return this.drawType;
            }
            set
            {
                if (this.drawType != value)
                {
                    this.drawType = value;
                    base.Invalidate();
                }
            }
        }

        [Category("Skin"), DefaultValue(0x12), Description("设置或获取图像的大小")]
        public int ImageWidth
        {
            get
            {
                return this._imageWidth;
            }
            set
            {
                if (value != this._imageWidth)
                {
                    this._imageWidth = (value < 12) ? 12 : value;
                    base.Invalidate();
                }
            }
        }

        [Category("MouseEnter"), Description("悬浮时背景")]
        public Image MouseBack
        {
            get
            {
                return this.mouseback;
            }
            set
            {
                if (this.mouseback != value)
                {
                    this.mouseback = value;
                    base.Invalidate();
                }
            }
        }

        [Category("MouseNorml"), Description("初始时背景")]
        public Image NormlBack
        {
            get
            {
                return this.normlback;
            }
            set
            {
                if (this.normlback != value)
                {
                    this.normlback = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(bool), "false"), Category("Skin"), Description("是否开启九宫绘图")]
        public bool Palace
        {
            get
            {
                return this.palace;
            }
            set
            {
                if (this.palace != value)
                {
                    this.palace = value;
                    base.Invalidate();
                }
            }
        }

        [Description("圆角大小"), DefaultValue(typeof(int), "8"), Category("Skin")]
        public int Radius
        {
            get
            {
                return this.radius;
            }
            set
            {
                if (this.radius != value)
                {
                    this.radius = (value < 4) ? 4 : value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(RoundStyle), "0"), Category("Skin"), Description("设置或获取按钮圆角的样式")]
        public RoundStyle RoundStyle
        {
            get
            {
                return this._roundStyle;
            }
            set
            {
                if (this._roundStyle != value)
                {
                    this._roundStyle = value;
                    base.Invalidate();
                }
            }
        }
    }
}


text:
/*globals define, $, _*/
/*jshint browser: true*/

/**
 * @author rkereskenyi / https://github.com/rkereskenyi
 */

define(['./ButtonBase', './ToolbarItemBase'], function (buttonBase, ToolbarItemBase) {

    'use strict';

    var ToolbarButton;

    ToolbarButton = function (params) {
        this.el = $('

');

        this._btn = buttonBase.createButton(params);

        this.el.append(this._btn);
    };

    _.extend(ToolbarButton.prototype, ToolbarItemBase.prototype);

    ToolbarButton.prototype.enabled = function (enabled) {
        this._btn.enabled(enabled);
    };

    return ToolbarButton;
});


text:
Little MVC framework to start working on any front&backend proyect

### Features
- Error reporting and Exception raising on redirects.
- Render views and template overwritting.
- User magnament.
- Database interface.

### Installation
1. Clone the repository
2. Create table in MySQL and excute `core/docs/db/users.sql`.
3. Create `app` folder on root.
3. Copy `core/config-sample.php` to `app/config.php` and fill it with your database credentials.
4. Read First steps.

### First steps

#### Create following folders into `app` folder:
- `controller`: Contains controllers with views logic. **Important:** controllers files must be called `<name>Controller.php`.
- `model`: Contains database models abstractions.
- `view`: Contains templates. You can overwrite `core` views creating again here.
- `lib`: Contains user libs and helpers.

#### Friendly routes
- By default `.htaccess` file make friendly user uri redirections with structure:
```
	/{controller}/{action}/{param}/{value}
```

- If you want, you can revert this redirections deleting `.htaccess` and refactoring all url to this structure:
```
	/index.php?c={controller}&a={action}&{param}={value}
```


text:
<Page loaded="loaded">
    <Page.actionBar>
        <ActionBar title="{{ L('items_title') }}">
            <ActionBar.actionItems>
                <ActionItem text="{{ L('share') }}" tap="share" ios.position="right" />
            </ActionBar.actionItems>
        </ActionBar>
    </Page.actionBar>
    <GridLayout rows="auto, *" columns="2*, *">
        <ActivityIndicator busy="{{ isLoading }}" rowSpan="2" colSpan="2" />
        <TextField id="grocery" text="{{ grocery }}" hint="{{ L('add_item_hint') }}" row="0" col="0"/>
        <Button text="{{ L('add') }}" tap="add" row="0" col="1"/>
        <ListView items="{{ groceryList }}" id="groceryList" row="1" colSpan="2">
            <ListView.itemTemplate>
                <GridLayout class="fa" columns="*, auto">
                    <Label text="{{ name }}"/>
                    <Button class="transparent-bg fa-lg grey" obj="{{ $value }}" text="" col="1" tap="delete"/>
                </GridLayout>
            </ListView.itemTemplate>
        </ListView>
    </GridLayout>
</Page>


text:
#include <tuple>

namespace overdrive {
	namespace util {
		// Sean Parents' for_each_argument (in C++17 this could be simplified further using fold expressions)
		// [NOTE] the order of evaluation is not determined
		template <typename Fn, typename...Args>
		void for_each_argument(Fn fn, Args&&... args);

		// using a different technique
		template <typename Fn, typename...Ts>
		void for_each_in_tuple(Fn fn, const std::tuple<Ts...>& tuple);
	}
}

#include "tuple.inl"


text:
declare function plural(n: number): number;
declare const _default: (string | number | (string[] | undefined)[] | number[] | (string | undefined)[] | typeof plural | {
    'AUD': string[];
    'JPY': string[];
    'USD': string[];
} | undefined)[];
export default _default;


text:
namespace foo
{
    // std:: denotes the "standard namespace"
    // cout takes a string as a stream and prints it to stdout
    // endl is the cross-platform stream version of an end-of-line character \n
    void print() { std::cout << "This is printing from foo." << std::endl; }
}

// Multiple namespaces may be defined easily
namespace bar
{
    // This is bar::print, which is distinct from foo::print above
    void print() {
        std::cout << "This is printing from bar." << std::endl;
    }
}

// Exactly like C, a C++ program must have a main function with arguments:
//   argc : int count of commandline arguments
//   argv : array of C-strings, meaning a pointer to an array of char pointers
int main(int argc, char **argv)
{
    // specify that everything in the namespace std should
    // become available in the local scope for convenience
    // NOTE: This is forbidden the Google style guide, but is included here
    //       for completeness - generally don't do this to keep namespaces clear
    using namespace std;

    // Example of command line usage
    if ( argc != 2 )
    {
        // The stream operator << automatically converts types
        // so here the C-string (char *) of argv[0] is converted to a
        // true C++ string, then passed as a stream to cout
        //
        // Note : the std prefix is not needed due to the "using" call above
        cout << "Usage: " << argv[0] << " arg1" << endl;
        return 1;
    }
    cout << "arg1 = " << argv[1] << endl;

    // Functions within distinct namespaces can be called directly
    foo::print();
    bar::print();

    // specify that print from foo:: should be pulled into local scope
    using foo::print;

    // demonstration that the foo:: prefix is no longer needed
    print();

    // define true string variable to hold input
    string input_str;

    // define float and int types to hold parsed input
    float fnum=0;
    int   inum=0;

    // Ask for input from user as a string
    cout << "Enter a float: ";

    // get entire line until a carriage return
    getline(cin, input_str);

    // use streams to parse the string input as different types
    stringstream(input_str) >> fnum;
    stringstream(input_str) >> inum;

    // show result of parsed input
    cout << "Input as a float: " << fnum << endl;
    cout << "Input as an int : " << inum << endl;

    // file handle
    ofstream output_file;

    // open a file
    output_file.open("output_file.txt");

    // check that file opened successfully
    if ( !output_file.is_open() )
    {
        // Print error to standard error (not standard out)
        cerr << "Error: Could not open file" << endl;
    }
    else
    {
        // write to file as a stream
        output_file << "This is the first line of the file." << endl;
        output_file << "Input as a float: " << fnum << '\t'; // \t = tab character
        output_file << "Input as an int : " << inum << endl;
        // explicitly close the file
        // (the file is also closed automatically when the program terminates)
        output_file.close();
    }

    // (this is implicit if omitted)
    return 0;
}


text:
<?php

  use osCommerce\OM\Core\HTML;
  use osCommerce\OM\Core\OSCOM;
  use osCommerce\OM\Core\Site\Admin\Application\CoreUpdate\CoreUpdate;
?>

<?php echo $OSCOM_Template->getIcon(32) . HTML::link(OSCOM::getLink(), $OSCOM_Template->getPageTitle()); ?>

<?php
  if ( $OSCOM_MessageStack->exists() ) {
    echo $OSCOM_MessageStack->get();
  }
?>

<form id="liveSearchForm">
  <?php echo HTML::inputField('search', null, 'id="liveSearchField" class="searchField" placeholder="' . OSCOM::getDef('placeholder_search') . '"') . HTML::button(array('type' => 'button', 'params' => 'onclick="osC_DataTable.reset();"', 'title' => OSCOM::getDef('button_reset'))); ?>

  <?php echo HTML::button(array('href' => OSCOM::getLink(), 'priority' => 'secondary', 'icon' => 'triangle-1-w', 'title' => OSCOM::getDef('button_back'))) . (CoreUpdate::getPackageInfo('version_from') == OSCOM::getVersion() ? ' ' . HTML::button(array('href' => OSCOM::getLink(null, null, 'Apply&Process&v=' . $_GET['v']), 'icon' => 'disk', 'title' => OSCOM::getDef('button_apply_update'))) : ''); ?>
</form>

      <?php echo OSCOM::getDef('table_heading_files'); ?>
      <?php echo OSCOM::getDef('table_heading_file_writable'); ?>
      <?php echo OSCOM::getDef('table_heading_file_custom'); ?>

  <?php echo '' . OSCOM::getDef('table_action_legend') . ' ' . OSCOM::getDef('legend_new') . ' ' . OSCOM::getDef('legend_modified') . ' ' . OSCOM::getDef('legend_to_delete') . ''; ?>


text:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.sjc.cc.entity.TccClusterConfig" table="T_CC_CLUSTER_CONFIG">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="identity">
			</generator>
        </id>
        <property name="uuid" type="java.lang.String">
            <column name="UUID" />
        </property>
        <property name="clusterName" type="java.lang.String">
            <column name="CLUSTERNAME" />
        </property>
        <property name="vcenter" type="java.lang.String">
            <column name="VCENTER" />
        </property>
        <property name="oldFlag" type="java.lang.String">
            <column name="OLDFLAG" />
        </property>
        <property name="vtype" type="java.lang.String">
            <column name="VTYPE" />
        </property>
        <property name="vcip" type="java.lang.String">
            <column name="VCIP" />
        </property>
        <property name="vcaccount" type="java.lang.String">
            <column name="VCACCOUNT" />
        </property>
        <property name="vcpassword" type="java.lang.String">
            <column name="VCPASSWORD" />
        </property>
        <property name="dcname" type="java.lang.String">
            <column name="DCNAME" />
        </property>
        <property name="zoneId" type="java.lang.String">
            <column name="ZONEID" />
        </property>
        <property name="cpuExceedRate" type="java.lang.Integer">
            <column name="CPU_EXCEED_RATE" />
        </property>
        <property name="ramExceedRate" type="java.lang.Integer">
            <column name="RAM_EXCEED_RATE" />
        </property>
        <property name="storageExceedRate" type="java.lang.Integer">
            <column name="STORAGE_EXCEED_RATE" />
        </property>
		<set name="tccPh" inverse="true">
            <key>
                <column name="CLUSTERID" />
            </key>
            <one-to-many class="com.sjc.cc.entity.TccPhysiscResourceInfo" />
        </set>
    </class>
</hibernate-mapping>


text:
package rres.knetminer.datasource.server.datasetinfo;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static rres.knetminer.api.ApiIT.CLI;

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

import org.junit.BeforeClass;
import org.junit.Test;

import rres.knetminer.api.ApiIT;
import rres.knetminer.datasource.api.config.DatasetInfo;
import rres.knetminer.datasource.api.config.KnetminerConfigTestUtils;
import rres.knetminer.datasource.api.config.SpecieInfo;

public class DatasetInfoServiceIT
{
	/**
	 * A wrapper of {@link ApiIT#synchToServer()} to synch the server init.
	 */
	@BeforeClass
	public static void synchToServer () throws Exception
	{
		ApiIT.synchToServer ();
	}

	/**
	 * Testing {@link DatasetInfo}.
	 * TODO: we need a test for {@link SpecieInfo} too.
	 */
	@Test
	public void testDatasetInfo ()
	{
		DatasetInfo dataset = CLI.datasetInfo ();
		assertNotNull ( "/data-set-info returns null!", dataset );
		assertTrue  (
			"no specie from /data-set-info!",
			Optional.ofNullable ( dataset.getSpecies () )
			.map ( List::size )
			.orElse ( 0 ) > 0
		);
	}

	/**
	 * Testing basemapXml for different taxIds.
	 */
	@Test
	public void testBasemapXml ()
	{
		testBasemapXml("4577");
		testBasemapXml("4565");
		testBasemapXml("3702");
	}

	/**
	 * Testing basemapXml.
	 */
	public void testBasemapXml (String taxId)
	{
		String dataset = CLI.basemapXml ( taxId );
		assertTrue  ( "Proper basemap.xml not exists for taxId " + taxId , dataset.contains ( "chromosome index" ) );

	}

	/**
	 * Testing ChromosomeIds for different taxIds.
	 */
	@Test
	public void testChromosomeIds ()
	{
		testChromosomeIds( "4577", 10, "6" );
		testChromosomeIds( "4565", 22, "1D" );
		testChromosomeIds( "3702", 5, "4" );
	}

	/**
	 * Testing ChromosomeIds.
	 */
	private void testChromosomeIds ( String taxId, int expectedLen, String expectedChr )
	{
		List<String> chrIds = CLI.chromosomeIds ( taxId );
		KnetminerConfigTestUtils.testChromosomeIds ( taxId, expectedLen, expectedChr, chrIds );
	}

	/**
	 * Testing sample-query.xml.
	 */
	@Test
	public void testSampleQueryXml ()
	{
		String queries = CLI.sampleQueryXml ();
		assertTrue  ( "SampleQuery XML is wrong", queries.contains ( "<sampleQueries>" ) );
	}

	/**
	 * Testing release-notes.html.
	 */
	@Test
	public void testReleaseNotes ()
	{
		String notes = CLI.releaseNotesHtml ();
		assertTrue  ( "Wrong result from /release-notes.html", notes.contains ( "ENSEMBL PLANTS (Arabidopsis thaliana)") );

	}

	/**
	 * Testing BackgroundImage
	 */
	@Test
	public void testBackgroundImage ()
	{
		byte[] img = CLI.backgroundImage ();
		assertTrue  ( "Empty result from /background-image!", img.length > 0 );

	}
}


text:
package dnsimple

import (
	"context"
	"io"
	"net/http"
	"testing"
)

func TestVanityNameServers_vanityNameServerPath(t *testing.T) {
	if want, got := "/1010/vanity/example.com", vanityNameServerPath("1010", "example.com"); want != got {
		t.Errorf("vanity_name_serverPath(%v,  ) = %v, want %v", "1010", got, want)
	}
}

func TestVanityNameServersService_EnableVanityNameServers(t *testing.T) {
	setupMockServer()
	defer teardownMockServer()

	mux.HandleFunc("/v2/1010/vanity/example.com", func(w http.ResponseWriter, r *http.Request) {
		httpResponse := httpResponseFixture(t, "/api/enableVanityNameServers/success.http")

		testMethod(t, r, "PUT")
		testHeaders(t, r)

		w.WriteHeader(httpResponse.StatusCode)
		_, _ = io.Copy(w, httpResponse.Body)
	})

	vanityNameServerResponse, err := client.VanityNameServers.EnableVanityNameServers(context.Background(), "1010", "example.com")
	if err != nil {
		t.Fatalf("VanityNameServers.EnableVanityNameServers() returned error: %v", err)
	}

	delegation := vanityNameServerResponse.Data[0].Name
	wantSingle := "ns1.example.com"

	if delegation != wantSingle {
		t.Fatalf("VanityNameServers.EnableVanityNameServers() returned %+v, want %+v", delegation, wantSingle)
	}
}

func TestVanityNameServersService_DisableVanityNameServers(t *testing.T) {
	setupMockServer()
	defer teardownMockServer()

	mux.HandleFunc("/v2/1010/vanity/example.com", func(w http.ResponseWriter, r *http.Request) {
		httpResponse := httpResponseFixture(t, "/api/disableVanityNameServers/success.http")

		testMethod(t, r, "DELETE")
		testHeaders(t, r)

		w.WriteHeader(httpResponse.StatusCode)
		_, _ = io.Copy(w, httpResponse.Body)
	})

	_, err := client.VanityNameServers.DisableVanityNameServers(context.Background(), "1010", "example.com")
	if err != nil {
		t.Fatalf("VanityNameServers.DisableVanityNameServers() returned error: %v", err)
	}
}


text:
---
layout: post
tags: [games, development, javascript, engine, 2d, shooter, space]
title: The JavasScript Space Shooter Game from 2013!
author: emir_osmanoski
comments: true
image: /images/2017-11-26-Space/Space.png
---

This is going to be a short one! Still in the middle of a bunch of other smaller
projects and this came up as a possibility and I wanted to keep up the momentum
of writing something!

So, I recently started looking at some old projects and repositories and ran
into the second and last ever game I'we worked on.

I also found what I consider the first, which is a Microsoft XNA educational
game on the solar system but I can't actually run it at the moment on the
account of XNA being basically deprecated and not usable on newer OSes.

There is a way, using MONO, but that sounds like a job for another time!

This second one though! It's JAVASCRIPT! **It's from 2013** and it still works!
Mostly....

So I downloaded it and fired it up and I thought I'd would be fun to take a look
at that code and see how things have generally changed in the last 5ish years.

![Space!]({{ site.baseurl }}/images/2017-11-26-Space/Space.png)

# Game Time!

Before going any further the game is actually available here:

PLAY!

# The inspiration and the game design

I remember that the actual inspiration of doing the little hobby project came
from a post I ran into at this subreddit. It was someone publishing a small set of game
assets for a 2d space type of game. Combining that with my interest in
JavaScript resulted in me spending some free time over the next period working
on it and the result became what we are looking at here.

For the purposes of this post I looked up the assets and they are still
available and actually have been expanded from what I remember was initially
published years back.

 If anyone is interested they can find the updated collection here.

## The Design! A Blast from the past!

The design of the game is very simple. You are a little spaceship and have waves
of enemies coming at you at the top and you can only move horizontally. When I
was a kid I've played tons of games using the similar approach and this was my
attempt at a very simplified version of that!

After killing enough enemies you advance to the next wave which increases the
difficulty of the game by:

1. Spawning enemies faster
2. Making enemies and projectiles faster.
3. Increasing the number of required enemy ships destroyed to advance to the
   next level!

You get 3 lives and after being hit by either an enemy or projectile you loose
one and gain an invulnerability shield for a couple of seconds.

When you run out of lives you are shown a Game Over Screen with  your score, the
enemy wave you reached and the time it took you to get there.

# Let's talk code!

KISS! Keep it simple and stupid! And this little project delivers on that!

At the time I wanted to learn a bit more about JavaScript so the game is
implemented without any frameworks (except jQuery!) using the basic Canvas API,
with jQuery as a support for implementing the simple game UI.

So without any further delay:

The Code

> Note: The plan was always to openly publish the project and maybe have someone else
> use some parts of for educational purposes or even to build something
> else on top of it.

The code is heavily commented. I did that both for my own sake, as a way to
verify/document the concepts and functionalities, and to make it easier for
someone else to pick it up!

Over the years I've come to think of commenting as a little pitfall. They are
bunch of better ways to make code understandable which don't rely on comments.
One of which is the code itself following stricter code quality patterns.

So let's just take a glimpse at some of the more core aspects and how things tie
in together.

We will also look at some infrastructural issues and challenges faced at the
time like managing dependencies and "building" the code.

## The Game Loop!

The magical game loop! Take User Input! Update State! Check State Conditions!
DRAW!!

The main game file which handles all that (among other things) is of course
main.js. It's the "App Root" and in a way contains all the calls to all the
other modules.

Let's take a look at two functions in the main.js module. The Start game and the
Game Loop

``` javascript

/*
	Called once all the assets are loaded.
	Hides the asset loading overlay and starts
	the initialization of major game modules.

*/

function startGame(){
	// Remove the "loading screen"
	$("#main-loading").hide();

	// Initialize dom ui
	g.domui.initDomUI(resetGame);

	// Start the background music
	// g.assets.backgroundMusic.loop().play().fadeIn();

	// Initialize the
	g.background.setupBackground();

	// Fully reset the game state
	resetGame();

	// Init the enemy spawner
	g.spawner.start();

	// Init the doodad spawner
	g.doodadspawner.start();

	// Setup the delta time functionality which is
	// covered in the main game loop
	g.last = new Date().getTime(),
	g.dt = 0;

	// Start the game loop
	gameLoop();
};

function gameLoop(){

	requestAnimFrame(gameLoop);

	// update delta time
	var now = new Date().getTime();
	g.dt = now - g.last;
	g.last = now;

	if(g.dt > 1000){
		g.dt = 1;
	}

	// clear the screen
	g.draw.Clear(g.ctx);

	// if the game is not over
	if(!g.state.isGameOver()){
		// Make the update call
		updateCall();

		// make the draw call
		drawCall();
	}
	else{
		if(g.state.getState() != g.state.gameStates.GameOverDisplayed){
			g.domui.showGameOverOverlay(
				g.state.getPlayerScore(),
				g.state.getCurrentWave(),
				g.state.getTimeElapsed());

			g.state.setState(g.state.gameStates.GameOverDisplayed);
		}
	}
};

```

Looking at  "startGame" we can see that it initializes a lot of other modules
that handle a collection of different things while the game is running. All of
these submodules are then given a chance to do some processing in the game loop
when the updateCall method is called.

But where is the loop?! And what's all this time *dt*(delta time)? One of the
bigger lessons in Canvas game development is managing how often the game loop
actually get's called.

One way to do that is of course with the setInterval JavaScript functionality,
but that does not guarantee that all the drawing operations and the browser will
be ready to process the code when the timeout is called.

A much better way as we can see above is the method call to requestAnimFrame and
passing the game loop method! The requestAnimFrame above is a wrapper over the
actual method (browser dependent) **requestAnimationFrame**

The implementation of the wrapper:

``` javascript

window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
})();

```

The wrapper (new global function) is just making sure to call the right (vendor)
version of the method. It also makes sure to fall back to a ~60fps timeout call
if no version of the requestAnimationFrame method is present.

You can read more about requestAnimationFrame here.

### Delta Time

The time and delta time calculations are actually used as a factor in any
updates that involve movement and animating things on the screen.

It comes down to the issue of us not knowing how much exactly time has passed
since the last time we ran updates so we might need to increase/decrease the
amount of space we move things to keep everything smoothly animated.

We notice that we set the Delta Time on the "Global" g/game variable so its
available in all the modules. We will take a quick look at how delta time is
used in one of the following sections.

## The Update and Draw Methods

Very briefly taking a look at the update and draw methods and look into some specific code around that.

``` javascript
/*
	The main update call. Calls the update methods
	on all the dependent and major modules of the game.
*/

function updateCall(){
	// call the background module update
	g.background.update();

	// update the enemy spawner
	g.spawner.update();

	// update the doodad spawner
	g.doodadspawner.update();

	// call the players update
	g.player.update();

	// call the update on the entity manager
	g.emanager.updateEntities();

	// update the particle system
	g.particle.update();

	g.state.update();
};

/*
	The main draw call. Calls the draw methods on
	all the dependend and major modules of the game.
*/

function drawCall() {
	// draw the background
	g.background.draw(g.ctx);

	// call the draw entities on the manager
	g.emanager.drawEntities(g.ctx);

	g.particle.draw(g.ctx);

	// draw the player
	g.player.draw(g.ctx);

	// draw the player
	g.state.draw(g.ctx);
};

```

Update and draw are pretty simple here. With each GameLoop Loop they call the
update and draw calls of the appropriate modules.

For example we can see that here we have the update and draw methods being
called for the player. Each draw call also gets the Canvas Context object from
the global g/game variable which is the actual Canvas API used to draw stuff on the Canvas.

To wrap up this code part let's take a look at the players update and draw methods. We will start with update:

``` javascript
/*
The update method is called from the main game loop
and allows the player entity to process what is going
on with the game and the input and update internal tracking
variables accordingly.

Its main use is to check for input on the game controls and
update player ship position and actions.

Update will also handle the visual blinking when the ship
cannot be hit by updating an internal drawPlayer variable
which is then used in the draw function to switch drawing
visibility.
*/

var update = function(){
	// Get key states and update player according to input
	var keyStates = g.input.keyState;

	var canvasWidth = g.canvas.width;

	if(keyStates["left"]){
		x -= speed * g.dt;
		activeImage = g.assets.playerLeft;

		// we need to determine if the
		// player went fully of screen to the
		// left side, and if so move him to appear
		//  on the right side of the screen.

		if(x <= 0 - width){
			// subtract the five so it becomes
			// more visible on the right side.
			x = canvasWidth - teleportMargin;
		}

	}
	else if(keyStates["right"]){
		x += speed * g.dt;
		activeImage = g.assets.playerRight;

		// same as when going to the left,
		//  we are checking if the player
		// moved out of the screen on the right side.
		if(x >= canvasWidth){
			x = (0 - width) + teleportMargin;
		}
	}
	else{
		// if we dont move
		activeImage = g.assets.player;
	}

	// If the fire binding was pressed
	// and released indicating a full key action.
	if(g.input.wasKeyFull("fire")){
		fireLaserSound();
		playerFireWeapon();
	}

	// Blinking section if the player cannot be hit
	if(!playerCanBeHit){

		g.domui.showPlayerLives(g.state.getPlayerLives());

		if(drawPlayer){
			setTimeout(function(){
				drawPlayer = false;
			}, 150)
		}
		else{
			setTimeout(function(){
				drawPlayer = true;
			}, 150)
		}
	}
	else{
		g.domui.hidePlayerLives();
		drawPlayer = true;
	}
};
```

The update method looks at the Input state (what the player has been doing with
the keys) and updates the Player's X coordinate. In our case the player is on a
fixed Y position.

> Here we can see the use of Delta Time. It is a factor taken into consideration
> when calculating the speed with which we will move the player in this
> update/draw loop. So if a lot of time has passed since the last time we
> reacted to player input to move, we will increase the movement/speed (and thus
> how much we move now) for the current update/draw loop

We also run some logic checks, like for example we handle the blinking by
checking the state of the playerCanBeHit variable. While it is true we change
the state of the drawPlayer variable which results in the player ship being
drawn for a couple of frames and then being hidden for a couple of frames, thus
resulting in a blinking animation.

After handling all our logic in update we can see that draw is fairly simple:

``` javascript
/*
The main player entity draw function that is reposinbie
for displaying the player ship sprite on the canvas
*/

var draw = function(ctx){

	if(drawPlayer){
		g.draw.DrawImage(ctx, activeImage, x, y);

		if(g.config.drawBoundingBoxes){
			g.draw.BoundingBox(ctx,getBoundingBox());
		}
	}
};
```

If the player is to be drawn we use a custom g.draw module to draw the player
Active Image. The player can have 3 active images based on the current movement
pattern. These 3 images are used to mimic tilting/animation when standing still,
or moving left or right.

## RMP

I remember at the time learning about polluting the global namespace in
JavaScript and different ways to approach that problem. One of the ways to avoid
it was using the Revealing Module Pattern.

So when looking at the code we can see it's a collection of modules that add/create
themselves under a single variable that lives in the global namespace: **window.game**

To ease the process of creating the modules  I even added a file that was just
that, a RMP template:

``` javascript
/*
	An attempt at implementing the javascript
	revealing module pattern for the major game components.

	Most of the components and javascript
	files are organized to follow this structure.
*/

(function(g){
	g.INSERT_MODULE_NAME_HERE = (function(){
		// ================= Inner constructor functions ============
		// ==========================================================

		// ======================== Properties =======================
		// ===========================================================

		// ======================== Public Functions =================
		// ===========================================================

		// ======================== Private Functions =================
		// ===========================================================

		// ======================== RMP ==============================
		// ===========================================================

		return {
		};

	})();
})(window.game = window.game || {});
```

By looking at the game loop we already saw that this is heavily used. Each
method called in update/draw is called on one of these modules!

You can read more about RMP here!

## The idea of re-use?!

There are a bunch of modules in the project that actually do a bunch of stuff
not necessarily related to the space ship style game. I remember that at one
point the idea was to move out certain parts and make them reusable for other
types of 2d games.

So certain modules like particle.js try to do just that. It's a very generic
module that offers some classes that can be used to draw any sprite based
"particles". Basically given a sprite sheet depicting particles it is able to
render the images for the given sprite in any location on the canvas.

There was a bunch of refactoring work left at the time to achieve that but
nonetheless it was an idea that was facilitated by the RMP pattern.

Let's now take a look at some of the "infrastructural" challenges!

> Before going any further there is a ton of stuff not covered here! Even things
> in main.js are not shown, mainly loading of all the game assets! Leaving it up
> to the reader to further explore the repository. And if someone could submit a
> PR with a fix for the sound not working, that would be great!

## Managing dependencies

What?! Are you crazy? Just download the jQuery version you need and slap it into
the **js** folder. What is not clear there?

Obviously this is a far cry from today's world of Bower (RIP), NPM, Yarn and so
on and so forth! But for such a simple requirement, hey guess what! It worked!

## Building the Game

One of the weirdest moments I had re-exploring the code base was the utilities
**sourceCompilation** folder. It contains some sort of a compiler that takes all
the modules and concatenates them in a single file. This compiled output can be
found in the src folder. The compiler even ran a obfuscation over the variable
names.

And what about the mechanism to replace the source files with the compiled
output? Looking at the script references in default.html might give us an answer
on how it was done:

``` html
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="js/soundjs-0.3.0.min.js"></script>
<script type="text/javascript" src="js/buzz.js"></script>
<script type="text/javascript" src="js/debug.js"></script>
<script type="text/javascript" src="js/loader.js"></script>
<script type="text/javascript" src="js/animation-api.js"></script>
<script type="text/javascript" src="js/draw.js"></script>
<script type="text/javascript" src="js/input.js"></script>
<script type="text/javascript" src="js/background.js"></script>
<script type="text/javascript" src="js/particle.js"></script>
<script type="text/javascript" src="js/emanager.js"></script>
<script type="text/javascript" src="js/projectile.js"></script>
<script type="text/javascript" src="js/doodad.js"></script>
<script type="text/javascript" src="js/enemy.js"></script>
<script type="text/javascript" src="js/spawner.js"></script>
<script type="text/javascript" src="js/doodadspawner.js"></script>
<script type="text/javascript" src="js/player.js"></script>

<script type="text/javascript" src="js/domui.js"></script>
<script type="text/javascript" src="js/state.js"></script>

<script type="text/javascript" src="js/configs.js"></script>

<!-- Should always be the last script added  as it starts the game -->
<script type="text/javascript" src="js/main.js"></script>

<!-- <script type="text/javascript" src="js/compiled_output.js"></script> -->
```

Yep just delete all the source file references and uncomment the compiled
output! Once again, it was enough for 5 years ago! I also never deployed this
thing anywhere that often that I needed anything more automatic!

Oh boy are things done differently today!

# Lessons Learned

To start wrapping up the article I will look into some lessons learned from the
project and the couple of key points I took away from it!

## JavaScript

One thing the project impressed on me in a way is that JavaScript can be really
fast! Thing is I'm not sure how true that is but apparently It's capable of
smoothly drawing a big amount of images on the screen at the same time, move
them around, animate frames, and make a ton of calculations to parallax animate
backgrounds.

It can process keyboard inputs and translate that to movement of said images,
all at the same time, and all while maintaining a stable frame rate!

So if it turns out that if any of the applications I'm working on today (mostly
Angular) are "slow" it means we are making some serious core mistakes somewhere.
Taking and validating user input in forms should never be slower or less
performant than flying spaceship around!

I also came out of it thinking that you can do anything with the language. That
gave me a sense of "security" when tackling today's more "boring" hard
challenges of displaying data in this way or that way, or updating table cells
based on dynamic differences in data or whatnot!

To summarize JavaScript was, still is and will probably continue to be my
favorite language. And I think this project has a big role in that! And I can't
wait to see what the future looks like!

TypeScript, I'm looking at you! In this case it also turns out that I can't wait
to see what the past had to offer! Go easy on me, I had some crazy deadlines and
different priorities with no wiggle room for new shiny TypeScript!

## Tooling

This one gets me! Today I can't image starting anything to do with JavaScript
without having NPM/YARN and Gulp as support. They just offer so much in terms of
quality of life and productivity! I mean LiveReload! Come on!

And yet 5 years ago apparently it did not matter. I had no problem hitting F5
each time code changes were made and it was enough to get this simple little
game finished.

Also the compiler nonsense was enough for the rare occasions I needed to minimize the code.

At the end today it's very simple to setup a *simple* build chain (GULP) I think
its not worth not having it!

# Summary

The year 2013 sure seems far away now and sure looks like a different time. I'm
glad I had the drive and opportunity to take some time to work on something like
this little game. I'm sure it was a welcome change of pace from the maybe
mundane daily work tasks.

It was also an amazing learning experience with some deep and resounding lessons
that follow me to this day.

But as is with most things, change is inevitable. The challenges and priorities
of today are different. Today we have Angular and React and Vue.js and a bunch
of other Front-End frameworks, tools and API's to learn about and master.

But nonetheless it was fun to step back and take a look in the past, even for a
short couple of days!

So, hopefully someone will find something here of use for their own journey! And
for bonus points here is the code for two additional old hobby projects: (I'm
never planning separate posts for these! One of these is enough!)

1. Static HTML Generator for a Bootstrap 3 Gallery

    If you give the console app a folder structure with images it will
    generate HTML with Bootstrap with image tags and appropriate Bootstrap
    functionality for showing all images in a gallery.

2. Bulk Download Bing Images for a given Keyword

    This is a strange one. I used it with the first repo to bulk download
    images and build custom galleries. Not sure why I used Bing though! I
    think their Image/Search API was more "open/understandable", if you could
    believe it, from Google's


text:
FROM mcr.microsoft.com/vscode/devcontainers/base:0-bullseye

COPY library-scripts/*.sh /tmp/library-scripts/

# [Option] Install zsh
ARG INSTALL_ZSH="true"
# [Option] Upgrade OS packages to their latest versions
ARG UPGRADE_PACKAGES="false"

# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
    && apt-get install -y graphviz \
    && apt-get clean -y && rm -rf /var/lib/apt/lists/*

# [Option] Install Azure CLI
ARG INSTALL_AZURE_CLI="true"
# [Option] Install Docker CLI
ARG INSTALL_DOCKER="true"
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
ENV NVM_DIR=/usr/local/share/nvm
ENV NVM_SYMLINK_CURRENT=true \
    PATH=${NVM_DIR}/current/bin:${PATH}
RUN if [ "${INSTALL_AZURE_CLI}" = "true" ]; then bash /tmp/library-scripts/azcli-debian.sh; fi \
    && if [ "${NODE_VERSION}" != "none" ]; then bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "${NODE_VERSION}" "${USERNAME}"; fi \
    && if [ "${INSTALL_DOCKER}" = "true" ]; then \
        bash /tmp/library-scripts/docker-debian.sh "true" "/var/run/docker-host.sock" "/var/run/docker.sock" "${USERNAME}"; \
    else \
        echo '#!/bin/bash\n"$@"' > /usr/local/share/docker-init.sh && chmod +x /usr/local/share/docker-init.sh; \
    fi \
    && rm -rf /var/lib/apt/lists/*

# Install Terraform, tflint, Terragrunt
ARG TERRAFORM_VERSION=0.12.16
ARG TFLINT_VERSION=0.8.2
ARG TERRAGRUNT_VERSION=0.28.1
RUN bash /tmp/library-scripts/terraform-debian.sh "${TERRAFORM_VERSION}" "${TFLINT_VERSION}" "${TERRAGRUNT_VERSION}" \
    && rm -rf /tmp/library-scripts

ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
CMD [ "sleep", "infinity" ]

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>


text:
import {HarnessPredicate} from '@angular/cdk/testing';
import {_MatSelectHarnessBase} from '@angular/material/select/testing';
import {
  MatLegacyOptionHarness,
  MatLegacyOptgroupHarness,
  LegacyOptionHarnessFilters,
  LegacyOptgroupHarnessFilters,
} from '@angular/material/legacy-core/testing';
import {LegacySelectHarnessFilters} from './select-harness-filters';

/**
 * Harness for interacting with a standard mat-select in tests.
 * @deprecated Use `MatSelectHarness` from `@angular/material/select/testing` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
 * @breaking-change 17.0.0
 */
export class MatLegacySelectHarness extends _MatSelectHarnessBase<
  typeof MatLegacyOptionHarness,
  MatLegacyOptionHarness,
  LegacyOptionHarnessFilters,
  typeof MatLegacyOptgroupHarness,
  MatLegacyOptgroupHarness,
  LegacyOptgroupHarnessFilters
> {
  static hostSelector = '.mat-select';
  protected _prefix = 'mat';
  protected _optionClass = MatLegacyOptionHarness;
  protected _optionGroupClass = MatLegacyOptgroupHarness;

  /**
   * Gets a `HarnessPredicate` that can be used to search for a `MatSelectHarness` that meets
   * certain criteria.
   * @param options Options for filtering which select instances are considered a match.
   * @return a `HarnessPredicate` configured with the given options.
   */
  static with(options: LegacySelectHarnessFilters = {}): HarnessPredicate<MatLegacySelectHarness> {
    return new HarnessPredicate(MatLegacySelectHarness, options);
  }
}


text:
<!DOCTYPE html>

    <title>Powerchord</title>
    <link rel="stylesheet" href="../bower_components/powergrid/css/powergrid.min.css">
    <link rel="stylesheet" href="../css/imports.css">
    <link rel="stylesheet" href="../css/powerchord.css">
    <link rel="stylesheet" href="style.css">

Powerchord

Typography

        Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
        Sed posuere interdum sem. Quisque ligula eros ullamcorper quis, lacinia quis facilisis sed sapien.
        Mauris varius diam vitae arcu. Sed arcu lectus auctor vitae, consectetuer et venenatis eget velit. Sed augue orci, lacinia eu tincidunt et eleifend nec lacus. Donec ultricies nisl ut felis, suspendisse potenti. Lorem ipsum ligula ut hendrerit mollis, ipsum erat vehicula risus, eu suscipit sem libero nec erat. Aliquam erat volutpat. Sed congue augue vitae neque. Nulla consectetuer porttitor pede. Fusce purus morbi tortor magna condimentum vel, placerat id blandit sit amet tortor.

Mauris sed libero. Suspendisse facilisis nulla in lacinia laoreet, lorem velit accumsan velit vel mattis libero nisl et sem. Proin interdum maecenas massa turpis sagittis in, interdum non lobortis vitae massa. Quisque purus lectus, posuere eget imperdiet nec sodales id arcu. Vestibulum elit pede dictum eu, viverra non tincidunt eu ligula.

Buttons

        <a class="btn">
        <button><button></button>
        <input type="button" value="<input type='button'>">

        <button class="btn-default">.btn-default</button>
        <button class="btn-secondary">.btn-secondary</button>
        <button class="btn-green">.btn-green</button>
        <button class="btn-yellow">.btn-yellow</button>
        <button class="btn-orange">.btn-orange</button>
        <button class="btn-red">.btn-red</button>
        <button class="btn-magenta">.btn-magenta</button>
        <button class="btn-blue">.btn-blue</button>
        <button class="btn-cyan">.btn-cyan</button>
        <button class="btn-gray">.btn-gray</button>
        <button class="btn-default" disabled>:disabled</button>

Forms

        Name
        <input id="text" type="text" placeholder="Firstname Familyname">

        Email
        <input id="email" type="email" placeholder="xxx@email.com">

        Gender

          <select id="gender">
            <option>Male</option>
            <option>Female</option>
            <option>Both</option>
            <option>Other</option>
          </select>

        Radio buttons
        <input id="radio01" type="radio" name="radio">
        True
        <input id="radio02" type="radio" name="radio">
        False
        <input id="radio03" type="radio" name="radio">
        File not found

        Checkboxes
        <input id="cb01" type="checkbox" name="cb">
        True
        <input id="cb02" type="checkbox" name="cb">
        False
        <input id="cb03" type="checkbox" name="cb">
        File not found

        <input type="submit" value="Send">

Forms (inline style)

        Name
        <input id="text2" type="text" placeholder="Firstname Familyname">

        Email
        <input id="email2" type="email" placeholder="xxx@email.com">

        Gender

          <select id="gender2">
            <option>Male</option>
            <option>Female</option>
            <option>Both</option>
            <option>Other</option>
          </select>

        Radio buttons
        <input id="radio11" type="radio" name="radio">
        True
        <input id="radio12" type="radio" name="radio">
        False
        <input id="radio13" type="radio" name="radio">
        File not found

        Checkboxes
        <input id="cb11" type="checkbox" name="cb">
        True
        <input id="cb12" type="checkbox" name="cb">
        False
        <input id="cb13" type="checkbox" name="cb">
        File not found

        <input type="submit" value="Send">


text:
"""
Copyright (c) 2021 Red Hat, Inc
All rights reserved.

This software may be modified and distributed under the terms
of the BSD license. See the LICENSE file for details.
"""
import logging
import reflink

from pathlib import Path
import shutil
from shutil import copytree
from typing import Dict, List, Callable, Iterable, Optional, TypeVar

from dockerfile_parse import DockerfileParser

from atomic_reactor.constants import (
    DOCKERFILE_FILENAME,
    EXPORTED_COMPRESSED_IMAGE_NAME_TEMPLATE,
    EXPORTED_SQUASHED_IMAGE_NAME,
    INSPECT_CONFIG,
)
from atomic_reactor.source import Source
from atomic_reactor.types import ImageInspectionData

logger = logging.getLogger(__name__)

def reflink_copy(src, dst, *, follow_symlinks=True):
    if follow_symlinks:
        reflink.reflink(str(Path(src).resolve()), str(dst))
    else:
        reflink.reflink(str(src), str(dst))

class DockerfileNotExist(Exception):
    """Dockerfile does not exist."""

class BuildDirIsNotInitialized(Exception):
    """Build directories are not initialized."""

    def __init__(self, msg: Optional[str] = None):
        super().__init__(msg or "Build directory is not initialized yet.")

class BuildDir(object):
    """Representing a directory which is specific to a platform."""

    def __init__(self, path: Path, platform: str) -> None:
        if not path.exists():
            raise FileNotFoundError(f"Build directory {path} does not exist.")
        self.path = path
        self.platform = platform
        self.exported_squashed_image: Path = self.path / EXPORTED_SQUASHED_IMAGE_NAME

    def exported_compressed_image(self, ext: str) -> Path:
        """Return the filename of an exported compressed image.

        :param str ext: the extension of the filename for a specific type of compress algorithm.
        :return: the absolute path to the file. Nothing is created in the filesystem.
        :rtype: pathlib.Path
        """
        return self.path / EXPORTED_COMPRESSED_IMAGE_NAME_TEMPLATE.format(ext)

    @property
    def dockerfile_path(self) -> Path:
        """An absolute path to the dockerfile within this build directory."""
        f = self.path / DOCKERFILE_FILENAME
        real_path = f.resolve()
        if real_path.parent != self.path:
            raise DockerfileNotExist(
                f"Dockerfile is linked from {real_path}, which is not supported."
            )
        return f

    @property
    def dockerfile(self) -> DockerfileParser:
        """Return the parsed Dockerfile.

        :return: the parsed Dockerfile.
        :rtype: DockerfileParser
        """
        return DockerfileParser(str(self.dockerfile_path))

    @staticmethod
    def _get_env_from_inspection(data: ImageInspectionData) -> Optional[Dict[str, str]]:
        """Get environment variables defined by ENV.

        :param data: the data inspected from an image.
        :type data: dict[str, any]
        :return: a mapping of environment variables got from the image
            inspection data. If no Env is found from the inspection data, None
            will be returned.
        :rtype: None or dict[str, str]
        """
        envs = data.get(INSPECT_CONFIG, {}).get("Env")
        if envs is None:
            return None
        if isinstance(envs, dict):
            return envs
        if isinstance(envs, list):
            return dict(item.split("=", 1) for item in envs)
        raise TypeError(f"Unexpected envs type: {type(envs)}; {envs!r}")

    def dockerfile_with_parent_env(self, parent_inspect: ImageInspectionData) -> DockerfileParser:
        """Get the parsed Dockerfile with parent information injected.

        :param parent_inspect: a mapping containing the image inspection data,
            which is used as parent image's inspection data to be injected into
            the parsed Dockerfile.
        :type parent_inspect: dict[str, any]
        :return: the parsed Dockerfile
        :rtype: DockerfileParser
        """
        envs = self._get_env_from_inspection(parent_inspect)
        if envs is None:
            logger.debug("Parent Environment not found, not applied to Dockerfile")
        return DockerfileParser(str(self.dockerfile_path), parent_env=envs)

FileCreationFunc = Callable[[BuildDir], Iterable[Path]]

T = TypeVar("T")

class RootBuildDir(object):
    """A directory containing all artifacts for building images.

    The following is a typical directory structure:

    /path/to/root_build_dir
    |-- aarch64/
    |-- ppc64le/
    |-- s390x/
    +-- x86_64/
    """

    def __init__(self, path: Path) -> None:
        if not path.exists():
            raise FileNotFoundError(f"Path {path} does not exist.")
        self.path = path
        self.platforms: List[str] = []

    @property
    def source_container_sources_dir(self) -> Path:
        """The directory holding sources for building a source container."""
        path: Path = self.path / "sources"
        path.mkdir(exist_ok=True)
        return path

    @property
    def source_container_output_dir(self) -> Path:
        """The directory holding the output from bsi for a source container build."""
        path: Path = self.path / "output"
        path.mkdir(exist_ok=True)
        return path

    def _copy_sources(self, source: Source) -> None:
        """Create platform-specific build directories from source.

        :param source: the original source from where to copy the content into
            every platform-specific directory.
        :type source: Source
        """
        src_path = source.path

        copy_method = shutil.copy2
        if reflink.supported_at(self.path):
            copy_method = reflink_copy
        logger.debug("copy method used for copy sources: %s", copy_method.__name__)

        for platform in self.platforms:
            copytree(src_path, self.path / platform, symlinks=True, copy_function=copy_method)

    @property
    def has_sources(self) -> bool:
        """Check if all platform-specific directories exist.

        :return: True if all platform-specific directories exist. Otherwise,
            False is returned.
        :rtype: bool
        """
        if not self.platforms:
            return False
        for platform in self.platforms:
            if not self.path.joinpath(platform).exists():
                return False
        return True

    def init_build_dirs(self, platforms: List[str], source: Source) -> None:
        """Initialize the root build directory with specific determined platforms.

        :param list[str] platforms: a list of platforms to build for.
        """
        self.platforms = sorted(platforms)
        if self.has_sources:
            return
        self._copy_sources(source)

    @property
    def any_platform(self) -> BuildDir:
        """Get a platform-specific build directory.

        This is typically used by code that does not care about platform. The
        returned directory is guaranteed to be the same one between the
        multiple calls.

        :return: a source directory.
        :rtype: BuildDir
        """
        if not self.has_sources:
            raise BuildDirIsNotInitialized()
        return self.platform_dir(self.platforms[0])

    def platform_dir(self, platform: str) -> BuildDir:
        """Get the build directory for the specified platform."""
        return BuildDir(self.path / platform, platform)

    def for_each_platform(self, action: Callable[[BuildDir], T]) -> Dict[str, T]:
        """Apply an action on every platform-specific directory.

        The action callable will be applied to the platform-specific
        directories in the order of the platforms specified when initializing
        this RootBuildDir object. The caller should not depend on or assume the
        order how action is applied.

        The action callable might raise errors, that will cause the
        ``for_each`` terminates immediately and the raised error is propagated
        to the caller. As a result, the action will not be applied to the rest
        of the platforms.

        :param action: a callable object that will be applied on every
            platform-specific directory. This callable must accept one single
            argument in BuildDir type, and it can return data in any type.
        :type action: Callable
        :return: a mapping from platform to the value returned from the
            function which is called for that platform.
        :rtype: dict[str, any]
        """
        if not self.has_sources:
            raise BuildDirIsNotInitialized()
        results: Dict[str, T] = {}
        for platform in self.platforms:
            results[platform] = action(self.platform_dir(platform))
        return results

    def for_all_platforms_copy(self, action: FileCreationFunc) -> List[Path]:
        """Ensure created files are present in all platform-specific directories.

        ``for_all_copy`` accepts either absolute or relative path returned from
        the action callable. Both normal file and directory are acceptable.
        Whatever the form of the path, it must be relative to the
        platform-specific directory where the file or directory is created.

        :param action: a callable that creates files in a given build directory
            and returns the files it created. The action accepts one single
            argument in type BuildDir, and returns an iterable object that
            yields paths of the created files.
        :type action: callable
        :return: the list of absolute paths of the created files.
        :rtype: list[pathlib.Path]
        """
        if not self.has_sources:
            raise BuildDirIsNotInitialized()

        build_dir = self.platform_dir(self.platforms[0])
        created_files = action(build_dir)

        the_new_files: List[Path] = []
        file_path: Path
        for file_path in created_files:
            if not file_path.is_absolute():
                file_path = build_dir.path / file_path
            file_path = file_path.resolve()
            if file_path == build_dir.path:
                raise ValueError(
                    f"{file_path} should not be added as a created directory."
                )
            try:
                file_path.relative_to(build_dir.path)
            except ValueError as e:
                raise ValueError(
                    f"File must be created inside the build directory. "
                    f"File {file_path} is not allowed."
                ) from e
            if not file_path.exists():
                raise FileNotFoundError(
                    f"{file_path} does not exist inside build directory."
                )
            the_new_files.append(file_path)

        copy_method = shutil.copy2
        if reflink.supported_at(self.path):
            copy_method = reflink_copy
        logger.debug("copy method used for all platforms copy: %s", copy_method.__name__)

        for platform in self.platforms[1:]:
            for src_file in the_new_files:
                dest = self.path / platform / src_file.relative_to(build_dir.path)

                if src_file.is_dir():
                    copytree(src_file, dest, symlinks=True, copy_function=copy_method)
                else:
                    dest.parent.mkdir(parents=True, exist_ok=True)
                    copy_method(src_file, dest, follow_symlinks=False)

        return the_new_files

class ContextDir:
    """Represents the context directory holding data through the whole image build pipeline."""

    def __init__(self, path: Path):
        if not path.exists():
            logger.debug("Context directory %s does not exist yet. Create it.", path)
            path.mkdir(parents=True)
        self._path = path
        self.workflow_json = path / "workflow.json"

    def get_platform_dir(self, platform: str) -> Path:
        """Get the directory specific to the specified platform.

        :param str platform: the platform of the directory. The value must be a
            valid platform supported by OSBS, e.g. x86_64.
        :return: path of the platform specific directory.
        :rtype: pathlib.Path
        :raise ValueError: if value of argument ``platform`` is empty or None.
        """
        if not platform:
            raise ValueError("No platform is specified.")
        platform_dir = self._path / platform
        platform_dir.mkdir(exist_ok=True)
        return platform_dir

    def get_platform_build_log(self, platform: str) -> Path:
        """Get platform-specific build log file."""
        return self._path / f"{platform}-build.log"


text:
/*!
 * node-sass: lib/extensions.js
 */

var flags = {},
    fs = require('fs'),
    package = require('../package.json'),
    path = require('path');

/**
 * Collect Arguments
 *
 * @param {Array} args
 * @api private
 */

function collectArguments(args) {
  for (var i = 0; i < args.length; i += 2) {
    if (args[i].lastIndexOf('--', 0) !== 0) {
      --i;
      continue;
    }

    flags[args[i]] = args[i + 1];
  }
}

/**
 * Get Runtime Info
 *
 * @api private
 */

function getRuntimeInfo() {
  var execPath = fs.realpathSync(process.execPath); // resolve symbolic link

  var runtime = execPath
               .split(/[\\/]+/).pop()
               .split('.').shift();

  runtime = runtime === 'nodejs' ? 'node' : runtime;

  return {
    name: runtime,
    execPath: execPath
  };
}

/**
 * Get binary name.
 * If environment variable SASS_BINARY_NAME or
 * process argument --binary-name is provided,
 * return it as is, otherwise make default binary
 * name: {platform}-{arch}-{v8 version}.node
 *
 * @api private
 */

function getBinaryName() {
  var binaryName;

  if (flags['--sass-binary-name']) {
    binaryName = flags['--sass-binary-name'];
  } else if (process.env.SASS_BINARY_NAME) {
    binaryName = process.env.SASS_BINARY_NAME;
  } else if (package.nodeSassConfig && package.nodeSassConfig.binaryName) {
    binaryName = package.nodeSassConfig.binaryName;
  } else {
    binaryName = [process.platform, '-',
                  process.arch, '-',
                  process.versions.modules].join('');
  }

  return [binaryName, 'binding.node'].join('_');
}

/**
 * Determine the URL to fetch binary file from.
 * By default feth from the node-sass distribution
 * site on GitHub.
 *
 * The default URL can be overriden using
 * the environment variable SASS_BINARY_SITE
 * or a command line option --sass-binary-site:
 *
 *   node scripts/install.js --sass-binary-site http://example.com/
 *
 * The URL should to the mirror of the repository
 * laid out as follows:
 *
 * SASS_BINARY_SITE/
 *
 *  v3.0.0
 *  v3.0.0/freebsd-x64-14_binding.node
 *  ....
 *  v3.0.0
 *  v3.0.0/freebsd-ia32-11_binding.node
 *  v3.0.0/freebsd-x64-42_binding.node
 *  ... etc. for all supported versions and platforms
 *
 * @api private
 */

function getBinaryUrl() {
  var site = flags['--sass-binary-site'] ||
             process.env.SASS_BINARY_SITE  ||
             package.nodeSassConfig.binarySite;
	return [site, 'v' + package.version, sass.binaryName].join('/');
}

collectArguments(process.argv.slice(2));

var sass = process.sass = {};

sass.binaryName = getBinaryName();
sass.binaryUrl = getBinaryUrl();
sass.runtime = getRuntimeInfo();

/**
 * Get binary path.
 * If environment variable SASS_BINARY_PATH or
 * process argument --sass-binary-path is provided,
 * select it by appending binary name, otherwise
 * make default binary path using binary name.
 * Once the primary selection is made, check if
 * callers wants to throw if file not exists before
 * returning.
 *
 * @param {Boolean} throwIfNotExists
 * @api private
 */

sass.getBinaryPath = function(throwIfNotExists) {
  var binaryPath;

  if (flags['--sass-binary-path']) {
    binaryPath = flags['--sass-binary-path'];
  } else if (process.env.SASS_BINARY_PATH) {
    binaryPath = process.env.SASS_BINARY_PATH;
  } else if (package.nodeSassConfig && package.nodeSassConfig.binaryPath) {
    binaryPath = package.nodeSassConfig.binaryPath;
  } else {
    binaryPath = path.join(__dirname, '..', 'vendor', sass.binaryName.replace(/_/, '/'));
  }

  if (!fs.existsSync(binaryPath) && throwIfNotExists) {
    throw new Error(['`libsass` bindings not found in ', binaryPath, '. Try reinstalling `node-sass`?'].join(''));
  }

  return binaryPath;
};

sass.binaryPath = sass.getBinaryPath();