text:
/* eslint-disable */

import Quill from '../quill.js';
import CodeBlock, { CodeBlockContainer } from '../formats/code';

import './helpers/unit';

import './unit/blots/scroll';
import './unit/blots/block';
import './unit/blots/block-embed';
import './unit/blots/inline';

import './unit/core/editor';
import './unit/core/selection';
import './unit/core/quill';

import './unit/formats/color';
import './unit/formats/link';
import './unit/formats/script';
import './unit/formats/align';
import './unit/formats/code';
import './unit/formats/header';
import './unit/formats/indent';
import './unit/formats/list';
import './unit/formats/bold';
import './unit/formats/table';

import './unit/modules/clipboard';
import './unit/modules/history';
import './unit/modules/keyboard';
import './unit/modules/syntax';
import './unit/modules/table';
import './unit/modules/toolbar';

import './unit/ui/picker';
import './unit/theme/base/tooltip';

// Syntax version will otherwise be registered
Quill.register(CodeBlockContainer, true);
Quill.register(CodeBlock, true);

export default Quill;


text:
package eu.hansolo.customstyleableskin;

import eu.hansolo.medusa.Fonts;
import eu.hansolo.medusa.Marker;
import eu.hansolo.medusa.Section;
import eu.hansolo.medusa.TickLabelOrientation;
import eu.hansolo.medusa.skins.GaugeSkinBase;
import eu.hansolo.medusa.tools.Helper;
import javafx.beans.InvalidationListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.CacheHint;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.InnerShadow;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.ArcType;
import javafx.scene.shape.Circle;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.FillRule;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.transform.Rotate;

import java.math.BigDecimal;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static eu.hansolo.medusa.tools.Helper.enableNode;

public class CustomPlainAmpSkin extends GaugeSkinBase {
    protected static final double                      PREFERRED_WIDTH  = 300;
    protected static final double                      PREFERRED_HEIGHT = 150;
    protected static final double                      MINIMUM_WIDTH    = 30;
    protected static final double                      MINIMUM_HEIGHT = 15;
    protected static final double                      MAXIMUM_WIDTH  = 1024;
    protected static final double                      MAXIMUM_HEIGHT = 858;
    private static final   double                      ASPECT_RATIO   = 0.5;
    private static final   double                      START_ANGLE    = 225;
    private static final   double                      ANGLE_RANGE    = 90;
    private                Map<Marker, Shape>          markerMap      = new ConcurrentHashMap<>();
    private                double                      oldValue;
    private                double                      width;
    private                double                      height;
    private                Pane                        pane;
    private                Canvas                      ticksAndSectionsCanvas;
    private                GraphicsContext             ticksAndSections;
    private                Pane                        markerPane;
    private                Path                        threshold;
    private                Path                        average;
    private                double                      ledSize;
    private                InnerShadow                 ledOnShadow;
    private                InnerShadow                 ledOffShadow;
    private                LinearGradient              frameGradient;
    private                LinearGradient              ledOnGradient;
    private                LinearGradient              ledOffGradient;
    private                RadialGradient              highlightGradient;
    private                Canvas                      ledCanvas;
    private                GraphicsContext             led;
    private                Path                        needle;
    private                MoveTo                      needleMoveTo1;
    private                CubicCurveTo                needleCubicCurveTo2;
    private                CubicCurveTo                needleCubicCurveTo3;
    private                CubicCurveTo                needleCubicCurveTo4;
    private                LineTo                      needleLineTo5;
    private                CubicCurveTo                needleCubicCurveTo6;
    private                ClosePath                   needleClosePath7;
    private                Rotate                      needleRotate;
    private                Group                       shadowGroup;
    private                DropShadow                  dropShadow;
    private                Text                        unitText;
    private                Rectangle                   lcd;
    private                Label                       lcdText;
    private                double                      angleStep;
    private                Tooltip                     thresholdTooltip;
    private                String                      formatString;
    private                Locale                      locale;
    private                ListChangeListener<Section> sectionListener;
    private                InvalidationListener        currentValueListener;
    private                InvalidationListener        needleRotateListener;
    private                ListChangeListener<Marker>  markerListener;

    // ******************** Constructors **************************************
    public CustomPlainAmpSkin(StyleableGauge gauge) {
        super(gauge);

        gauge.getStylesheets().add(CustomPlainAmpSkin.class.getResource("custom-plain-amp.css").toExternalForm());

        if (gauge.isAutoScale()) gauge.calcAutoScale();
        angleStep            = gauge.getAngleRange() / gauge.getRange();
        oldValue             = gauge.getValue();
        formatString         = new StringBuilder("%.").append(Integer.toString(gauge.getDecimals())).append("f").toString();
        locale               = gauge.getLocale();
        sectionListener      = c -> redraw();
        currentValueListener = o -> rotateNeedle();
        needleRotateListener = o -> handleEvents("ANGLE");
        markerListener       = c -> {
            updateMarkers();
            redraw();
        };

        updateMarkers();

        initGraphics();
        registerListeners();
    }

    // ******************** Initialization ************************************
    private void initGraphics() {
        // Set initial size
        if (Double.compare(gauge.getPrefWidth(), 0.0) <= 0 || Double.compare(gauge.getPrefHeight(), 0.0) <= 0 ||
            Double.compare(gauge.getWidth(), 0.0) <= 0 || Double.compare(gauge.getHeight(), 0.0) <= 0) {
            if (gauge.getPrefWidth() > 0 && gauge.getPrefHeight() > 0) {
                gauge.setPrefSize(gauge.getPrefWidth(), gauge.getPrefHeight());
            } else {
                gauge.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
            }
        }

        ticksAndSectionsCanvas = new Canvas(PREFERRED_WIDTH, PREFERRED_HEIGHT);
        ticksAndSections       = ticksAndSectionsCanvas.getGraphicsContext2D();

        ledCanvas = new Canvas();
        led       = ledCanvas.getGraphicsContext2D();

        thresholdTooltip = new Tooltip("Threshold\n(" + String.format(locale, formatString, gauge.getThreshold()) + ")");
        thresholdTooltip.setTextAlignment(TextAlignment.CENTER);

        threshold = new Path();
        Helper.enableNode(threshold, gauge.isThresholdVisible());
        Tooltip.install(threshold, thresholdTooltip);

        average = new Path();
        Helper.enableNode(average, gauge.isAverageVisible());

        markerPane = new Pane();

        needleRotate = new Rotate(180 - START_ANGLE);
        needleRotate.setAngle(needleRotate.getAngle() + (gauge.getValue() - oldValue - gauge.getMinValue()) * angleStep);

        needleMoveTo1       = new MoveTo();
        needleCubicCurveTo2 = new CubicCurveTo();
        needleCubicCurveTo3 = new CubicCurveTo();
        needleCubicCurveTo4 = new CubicCurveTo();
        needleLineTo5       = new LineTo();
        needleCubicCurveTo6 = new CubicCurveTo();
        needleClosePath7    = new ClosePath();
        needle              = new Path(needleMoveTo1, needleCubicCurveTo2, needleCubicCurveTo3, needleCubicCurveTo4, needleLineTo5, needleCubicCurveTo6, needleClosePath7);
        needle.setFillRule(FillRule.EVEN_ODD);
        needle.getTransforms().setAll(needleRotate);
        needle.getStyleClass().add("needle");

        dropShadow = new DropShadow();
        dropShadow.setColor(Color.rgb(0, 0, 0, 0.25));
        dropShadow.setBlurType(BlurType.TWO_PASS_BOX);
        dropShadow.setRadius(0.015 * PREFERRED_WIDTH);
        dropShadow.setOffsetY(0.015 * PREFERRED_WIDTH);

        shadowGroup = new Group(needle);
        shadowGroup.setEffect(gauge.isShadowsEnabled() ? dropShadow : null);
        shadowGroup.getStyleClass().add("shadow-group");

        unitText = new Text(gauge.getUnit());
        unitText.setMouseTransparent(true);
        unitText.setTextOrigin(VPos.CENTER);
        unitText.getStyleClass().add("unit");

        lcd = new Rectangle(0.3 * PREFERRED_WIDTH, 0.1 * PREFERRED_HEIGHT);
        lcd.setArcWidth(0.0125 * PREFERRED_HEIGHT);
        lcd.setArcHeight(0.0125 * PREFERRED_HEIGHT);
        lcd.relocate((PREFERRED_WIDTH - lcd.getWidth()) * 0.5, 0.66 * PREFERRED_HEIGHT);
        lcd.getStyleClass().add("lcd");
        Helper.enableNode(lcd, gauge.isLcdVisible() && gauge.isValueVisible());

        lcdText = new Label(String.format(locale, "%." + gauge.getDecimals() + "f", gauge.getValue()));
        lcdText.setAlignment(Pos.CENTER_RIGHT);
        lcdText.setVisible(gauge.isValueVisible());
        lcdText.getStyleClass().add("lcd-foreground");

        // Set initial value
        angleStep          = ANGLE_RANGE / gauge.getRange();
        double targetAngle = 180 - START_ANGLE + (gauge.getValue() - gauge.getMinValue()) * angleStep;
        targetAngle        = clamp(180 - START_ANGLE, 180 - START_ANGLE + ANGLE_RANGE, targetAngle);
        needleRotate.setAngle(targetAngle);

        // Add all nodes
        pane = new Pane();
        pane.getChildren().setAll(ticksAndSectionsCanvas,
                                  markerPane,
                                  ledCanvas,
                                  unitText,
                                  lcd,
                                  lcdText,
                                  shadowGroup);
        pane.getStyleClass().add("background-pane");

        getChildren().setAll(pane);
    }

    @Override protected void registerListeners() {
        super.registerListeners();

        gauge.getMarkers().addListener(markerListener);
        gauge.getSections().addListener(sectionListener);
        gauge.currentValueProperty().addListener(currentValueListener);
        needleRotate.angleProperty().addListener(needleRotateListener);

        if (gauge instanceof StyleableGauge) {
            ((StyleableGauge) gauge).styleableTickmarkColorProperty().addListener((o, ov, nv) -> gauge.setTickMarkColor(nv));
            ((StyleableGauge) gauge).styleableTicklabelColorProperty().addListener((o, ov, nv) -> gauge.setTickLabelColor(nv));
        }
    }

    // ******************** Methods *******************************************
    protected void handleEvents(final String EVENT_TYPE) {
        super.handleEvents(EVENT_TYPE);
        if ("FINISHED".equals(EVENT_TYPE)) {
            if ( gauge.isHighlightSections() ) {
                redraw();
            }
        } else if ("ANGLE".equals(EVENT_TYPE)) {
            double currentValue = (needleRotate.getAngle() + START_ANGLE - 180) / angleStep + gauge.getMinValue();
            lcdText.setText((String.format(locale, formatString, currentValue)));
            if (gauge.isLcdVisible()) {
                lcdText.setAlignment(Pos.CENTER_RIGHT);
                lcdText.setTranslateX((width - lcdText.getPrefWidth()) * 0.5);
            } else {
                lcdText.setAlignment(Pos.CENTER);
                lcdText.setTranslateX((width - lcdText.getLayoutBounds().getWidth()) * 0.5);
            }
        } else if ("VISIBILITY".equals(EVENT_TYPE)) {
            enableNode(ledCanvas, gauge.isLedVisible());
            enableNode(unitText, !gauge.getUnit().isEmpty());
            enableNode(lcd,gauge.isLcdVisible());
            enableNode(lcdText,gauge.isValueVisible());
            enableNode(threshold, gauge.isThresholdVisible());
            enableNode(average, gauge.isAverageVisible());
            boolean markersVisible = gauge.getMarkersVisible();
            for (Shape shape : markerMap.values()) { Helper.enableNode(shape, markersVisible); }
            resize();
            redraw();
        } else if ("LED".equals(EVENT_TYPE)) {
            if (gauge.isLedVisible()) { drawLed(led); }
        } else if ("LCD".equals(EVENT_TYPE)) {
            if (gauge.isLcdVisible()) redraw();
        } else if ("RECALC".equals(EVENT_TYPE)) {
            angleStep = gauge.getAngleStep();
            if (gauge.getValue() < gauge.getMinValue()) {
                oldValue = gauge.getMinValue();
            }
            if (gauge.getValue() > gauge.getMaxValue()) {
                oldValue = gauge.getMaxValue();
            }
            redraw();
            rotateNeedle();
        }
    }

    // ******************** Private Methods ***********************************
    private void rotateNeedle() {
        angleStep          = ANGLE_RANGE / (gauge.getRange());
        double targetAngle = 180 - START_ANGLE + (gauge.getCurrentValue() - gauge.getMinValue()) * angleStep;
        targetAngle        = clamp(180 - START_ANGLE, 180 - START_ANGLE + ANGLE_RANGE, targetAngle);
        needleRotate.setAngle(targetAngle);
        if (gauge.isAverageVisible()) drawAverage();
    }

    private void drawMarkers() {
        markerPane.getChildren().setAll(markerMap.values());
        markerPane.getChildren().addAll(average, threshold);
        double minValue    = gauge.getMinValue();
        double markerSize  = 0.0125 * width;
        double pathHalf    = markerSize * 0.3;
        double scaledWidth = width * 1.106;
        double centerX     = width * 0.5;
        double centerY     = height * 1.4;
        if (gauge.getMarkersVisible()) {
            for (Map.Entry<Marker, Shape> entry : markerMap.entrySet()) {
                Marker marker     = entry.getKey();
                Shape  shape      = entry.getValue();
                double valueAngle = START_ANGLE - (marker.getValue() - minValue) * angleStep;
                double sinValue   = Math.sin(Math.toRadians(valueAngle));
                double cosValue   = Math.cos(Math.toRadians(valueAngle));
                switch (marker.getMarkerType()) {
                    case TRIANGLE:
                        Path triangle = (Path) shape;
                        triangle.getElements().clear();
                        triangle.getElements().add(new MoveTo(centerX + scaledWidth * 0.38 * sinValue, centerY + scaledWidth * 0.38 * cosValue));
                        sinValue = Math.sin(Math.toRadians(valueAngle - pathHalf));
                        cosValue = Math.cos(Math.toRadians(valueAngle - pathHalf));
                        triangle.getElements().add(new LineTo(centerX + scaledWidth * 0.4075 * sinValue, centerY + scaledWidth * 0.4075 * cosValue));
                        sinValue = Math.sin(Math.toRadians(valueAngle + pathHalf));
                        cosValue = Math.cos(Math.toRadians(valueAngle + pathHalf));
                        triangle.getElements().add(new LineTo(centerX + scaledWidth * 0.4075 * sinValue, centerY + scaledWidth * 0.4075 * cosValue));
                        triangle.getElements().add(new ClosePath());
                        break;
                    case DOT:
                        Circle dot = (Circle) shape;
                        dot.setRadius(markerSize);
                        dot.setCenterX(centerX + scaledWidth * 0.3945 * sinValue);
                        dot.setCenterY(centerY + scaledWidth * 0.3945 * cosValue);
                        break;
                    case STANDARD:
                    default:
                        Path standard = (Path) shape;
                        standard.getElements().clear();
                        standard.getElements().add(new MoveTo(centerX + scaledWidth * 0.38 * sinValue, centerY + scaledWidth * 0.38 * cosValue));
                        sinValue = Math.sin(Math.toRadians(valueAngle - pathHalf));
                        cosValue = Math.cos(Math.toRadians(valueAngle - pathHalf));
                        standard.getElements().add(new LineTo(centerX + scaledWidth * 0.4075 * sinValue, centerY + scaledWidth * 0.4075 * cosValue));
                        standard.getElements().add(new LineTo(centerX + scaledWidth * 0.43   * sinValue, centerY + scaledWidth * 0.43   * cosValue));
                        sinValue = Math.sin(Math.toRadians(valueAngle + pathHalf));
                        cosValue = Math.cos(Math.toRadians(valueAngle + pathHalf));
                        standard.getElements().add(new LineTo(centerX + scaledWidth * 0.43   * sinValue, centerY + scaledWidth * 0.43   * cosValue));
                        standard.getElements().add(new LineTo(centerX + scaledWidth * 0.4075 * sinValue, centerY + scaledWidth * 0.4075 * cosValue));
                        standard.getElements().add(new ClosePath());
                        break;
                }
                Color markerColor = marker.getColor();
                shape.setFill(markerColor);
                shape.setStroke(markerColor.darker());
                shape.setPickOnBounds(false);
                Tooltip markerTooltip;
                if (marker.getText().isEmpty()) {
                    markerTooltip = new Tooltip(Double.toString(marker.getValue()));
                } else {
                    markerTooltip = new Tooltip(new StringBuilder(marker.getText()).append("\n(").append(Double.toString(marker.getValue())).append(")").toString());
                }
                markerTooltip.setTextAlignment(TextAlignment.CENTER);
                Tooltip.install(shape, markerTooltip);
                shape.setOnMousePressed(e -> marker.fireMarkerEvent(marker.MARKER_PRESSED_EVENT));
                shape.setOnMouseReleased(e -> marker.fireMarkerEvent(marker.MARKER_RELEASED_EVENT));
            }
        }

        if (gauge.isThresholdVisible()) {
            // Draw threshold
            threshold.getElements().clear();
            double thresholdAngle = START_ANGLE - (gauge.getThreshold() - minValue) * angleStep;
            double thresholdSize  = Helper.clamp(2.0, 2.5, 0.01 * scaledWidth);
            double sinValue       = Math.sin(Math.toRadians(thresholdAngle));
            double cosValue       = Math.cos(Math.toRadians(thresholdAngle));
            threshold.getElements().add(new MoveTo(centerX + scaledWidth * 0.38 * sinValue, centerY + scaledWidth * 0.38 * cosValue));
            sinValue = Math.sin(Math.toRadians(thresholdAngle - thresholdSize));
            cosValue = Math.cos(Math.toRadians(thresholdAngle - thresholdSize));
            threshold.getElements().add(new LineTo(centerX + scaledWidth * 0.35 * sinValue, centerY + scaledWidth * 0.35 * cosValue));
            sinValue = Math.sin(Math.toRadians(thresholdAngle + thresholdSize));
            cosValue = Math.cos(Math.toRadians(thresholdAngle + thresholdSize));
            threshold.getElements().add(new LineTo(centerX + scaledWidth * 0.35 * sinValue, centerY + scaledWidth * 0.35 * cosValue));
            threshold.getElements().add(new ClosePath());
            threshold.setFill(gauge.getThresholdColor());
            threshold.setStroke(gauge.getTickMarkColor());
        }
    }

    private void drawAverage() {
        double scaledWidth = width * 1.106;
        double centerX     = width * 0.5;
        double centerY     = height * 1.4;
        double minValue    = gauge.getMinValue();
        // Draw average
        average.getElements().clear();
        double averageAngle = START_ANGLE - (gauge.getAverage() - minValue) * angleStep;
        double averageSize  = Helper.clamp(2.0, 2.5, 0.01 * scaledWidth);
        double sinValue     = Math.sin(Math.toRadians(averageAngle));
        double cosValue     = Math.cos(Math.toRadians(averageAngle));
        average.getElements().add(new MoveTo(centerX + scaledWidth * 0.38 * sinValue, centerY + scaledWidth * 0.38 * cosValue));
        sinValue = Math.sin(Math.toRadians(averageAngle - averageSize));
        cosValue = Math.cos(Math.toRadians(averageAngle - averageSize));
        average.getElements().add(new LineTo(centerX + scaledWidth * 0.35 * sinValue, centerY + scaledWidth * 0.35 * cosValue));
        sinValue = Math.sin(Math.toRadians(averageAngle + averageSize));
        cosValue = Math.cos(Math.toRadians(averageAngle + averageSize));
        average.getElements().add(new LineTo(centerX + scaledWidth * 0.35 * sinValue, centerY + scaledWidth * 0.35 * cosValue));
        average.getElements().add(new ClosePath());
        average.setFill(gauge.getAverageColor());
        average.setStroke(gauge.getTickMarkColor());
    }

    private void updateMarkers() {
        markerMap.clear();
        for (Marker marker : gauge.getMarkers()) {
            switch(marker.getMarkerType()) {
                case TRIANGLE: markerMap.put(marker, new Path()); break;
                case DOT     : markerMap.put(marker, new Circle()); break;
                case STANDARD:
                default:       markerMap.put(marker, new Path()); break;
            }
        }
    }

    private void drawTickMarks(final GraphicsContext CTX) {
        double  sinValue;
        double  cosValue;
        double  orthText       = TickLabelOrientation.ORTHOGONAL == gauge.getTickLabelOrientation() ? 0.61 : 0.62;
        Point2D center         = new Point2D(width * 0.5, height * 1.4);
        double  minorTickSpace = gauge.getMinorTickSpace();
        double  minValue       = gauge.getMinValue();
        //double     maxValue         = gauge.getMaxValue();
        double     tmpAngleStep     = angleStep * minorTickSpace;
        int        decimals         = gauge.getTickLabelDecimals();
        BigDecimal minorTickSpaceBD = BigDecimal.valueOf(minorTickSpace);
        BigDecimal majorTickSpaceBD = BigDecimal.valueOf(gauge.getMajorTickSpace());
        BigDecimal mediumCheck2     = BigDecimal.valueOf(2 * minorTickSpace);
        BigDecimal mediumCheck5     = BigDecimal.valueOf(5 * minorTickSpace);
        BigDecimal counterBD        = BigDecimal.valueOf(minValue);
        double     counter          = minValue;

        Font tickLabelFont = Fonts.robotoCondensedRegular((decimals == 0 ? 0.07 : 0.068) * height);
        CTX.setFont(tickLabelFont);

        for (double angle = 0 ; Double.compare(-ANGLE_RANGE - tmpAngleStep, angle) < 0 ; angle -= tmpAngleStep) {
            sinValue = Math.sin(Math.toRadians(angle + START_ANGLE));
            cosValue = Math.cos(Math.toRadians(angle + START_ANGLE));

            Point2D innerPoint       = new Point2D(center.getX() + width * 0.51987097 * sinValue, center.getY() + width * 0.51987097 * cosValue);
            Point2D outerMinorPoint  = new Point2D(center.getX() + width * 0.55387097 * sinValue, center.getY() + width * 0.55387097 * cosValue);
            Point2D outerMediumPoint = new Point2D(center.getX() + width * 0.56387097 * sinValue, center.getY() + width * 0.56387097 * cosValue);
            Point2D outerPoint       = new Point2D(center.getX() + width * 0.58387097 * sinValue, center.getY() + width * 0.58387097 * cosValue);
            Point2D textPoint        = new Point2D(center.getX() + width * orthText * sinValue, center.getY() + width * orthText * cosValue);

            CTX.setStroke(gauge.getTickMarkColor());
            if (Double.compare(counterBD.remainder(majorTickSpaceBD).doubleValue(), 0.0) == 0) {
                // Draw major tickmark
                CTX.setLineWidth(height * 0.0055);
                CTX.strokeLine(innerPoint.getX(), innerPoint.getY(), outerPoint.getX(), outerPoint.getY());

                // Draw text
                CTX.save();
                CTX.translate(textPoint.getX(), textPoint.getY());
                switch(gauge.getTickLabelOrientation()) {
                    case ORTHOGONAL:
                        if ((360 - START_ANGLE - angle) % 360 > 90 && (360 - START_ANGLE - angle) % 360 < 270) {
                            CTX.rotate((180 - START_ANGLE - angle) % 360);
                        } else {
                            CTX.rotate((360 - START_ANGLE - angle) % 360);
                        }
                        break;
                    case TANGENT:
                        if ((360 - START_ANGLE - angle - 90) % 360 > 90 && (360 - START_ANGLE - angle - 90) % 360 < 270) {
                            CTX.rotate((90 - START_ANGLE - angle) % 360);
                        } else {
                            CTX.rotate((270 - START_ANGLE - angle) % 360);
                        }
                        break;
                    case HORIZONTAL:
                    default:
                        break;
                }
                CTX.setTextAlign(TextAlignment.CENTER);
                CTX.setTextBaseline(VPos.CENTER);
                CTX.setFill(gauge.getTickLabelColor());
                CTX.fillText(String.format(locale, "%." + decimals + "f", counter), 0, 0);
                CTX.restore();
            } else if (gauge.getMediumTickMarksVisible() &&
                       Double.compare(minorTickSpaceBD.remainder(mediumCheck2).doubleValue(), 0.0) != 0.0 &&
                       Double.compare(counterBD.remainder(mediumCheck5).doubleValue(), 0.0) == 0.0) {
                CTX.setLineWidth(height * 0.0035);
                CTX.strokeLine(innerPoint.getX(), innerPoint.getY(), outerMediumPoint.getX(), outerMediumPoint.getY());
            } else if (gauge.getMinorTickMarksVisible() && Double.compare(counterBD.remainder(minorTickSpaceBD).doubleValue(), 0.0) == 0) {
                CTX.setLineWidth(height * 0.00225);
                CTX.strokeLine(innerPoint.getX(), innerPoint.getY(), outerMinorPoint.getX(), outerMinorPoint.getY());
            }
            counterBD = counterBD.add(minorTickSpaceBD);
            counter   = counterBD.doubleValue();
        }
    }

    private void drawSections(final GraphicsContext CTX) {
        final double                  x                 = -width * 0.03;
        final double                  y                 = height * 0.345;
        final double                  w                 = width * 1.06;
        final double                  h                 = height * 2.085;
        final double                  MIN_VALUE         = gauge.getMinValue();
        final double                  MAX_VALUE         = gauge.getMaxValue();
        final double                  OFFSET            = 90 - START_ANGLE;
        final ObservableList<Section> sections          = gauge.getSections();
        final boolean                 highlightSections = gauge.isHighlightSections();

        double value    = gauge.getCurrentValue();
        int    listSize = sections.size();
        for (int i = 0 ; i < listSize ; i++) {
            final Section SECTION = sections.get(i);
            final double  SECTION_START_ANGLE;
            if (Double.compare(SECTION.getStart(), MAX_VALUE) <= 0 && Double.compare(SECTION.getStop(), MIN_VALUE) >= 0) {
                if (SECTION.getStart() < MIN_VALUE && SECTION.getStop() < MAX_VALUE) {
                    SECTION_START_ANGLE = 0;
                } else {
                    SECTION_START_ANGLE = (SECTION.getStart() - MIN_VALUE) * angleStep;
                }
                final double SECTION_ANGLE_EXTEND;
                if (SECTION.getStop() > MAX_VALUE) {
                    SECTION_ANGLE_EXTEND = (MAX_VALUE - SECTION.getStart()) * angleStep;
                } else {
                    SECTION_ANGLE_EXTEND = (SECTION.getStop() - SECTION.getStart()) * angleStep;
                }

                CTX.save();
                if (highlightSections) {
                    CTX.setStroke(SECTION.contains(value) ? SECTION.getHighlightColor() : SECTION.getColor());
                } else {
                    CTX.setStroke(SECTION.getColor());
                }
                CTX.setLineWidth(height * 0.0415);
                CTX.setLineCap(StrokeLineCap.BUTT);
                CTX.strokeArc(x, y, w, h, -(OFFSET + SECTION_START_ANGLE), -SECTION_ANGLE_EXTEND, ArcType.OPEN);
                CTX.restore();
            }
        }
    }

    private void drawLed(final GraphicsContext CTX) {
        CTX.clearRect(0, 0, ledSize, ledSize);
        CTX.setFill(frameGradient);
        CTX.fillOval(0, 0, ledSize, ledSize);

        CTX.save();
        if (gauge.isLedOn()) {
            CTX.setEffect(ledOnShadow);
            CTX.setFill(ledOnGradient);
        } else {
            CTX.setEffect(ledOffShadow);
            CTX.setFill(ledOffGradient);
        }
        CTX.fillOval(0.14 * ledSize, 0.14 * ledSize, 0.72 * ledSize, 0.72 * ledSize);
        CTX.restore();

        CTX.setFill(highlightGradient);
        CTX.fillOval(0.21 * ledSize, 0.21 * ledSize, 0.58 * ledSize, 0.58 * ledSize);
    }

    private double clamp(final double MIN_VALUE, final double MAX_VALUE, final double VALUE) {
        if (VALUE < MIN_VALUE) return MIN_VALUE;
        if (VALUE > MAX_VALUE) return MAX_VALUE;
        return VALUE;
    }

    private void resizeStaticText() {
        double maxWidth = width * 0.3;
        double fontSize = height * 0.15;

        unitText.setFont(Fonts.robotoMedium(fontSize));
        unitText.setText(gauge.getUnit());
        if ( unitText.getLayoutBounds().getWidth() > maxWidth ) {
            Helper.adjustTextSize(unitText, maxWidth, fontSize);
        }
        unitText.setTranslateX((width - unitText.getLayoutBounds().getWidth()) * 0.5);
        unitText.setTranslateY(height * 0.55);
    }

    private void resizeText() {
        resizeStaticText();

        if (gauge.isLcdVisible()) {

            lcdText.setPadding(new Insets(0, 0.005 * width, 0, 0.005 * width));

            switch(gauge.getLcdFont()) {
                case LCD:
                    lcdText.setFont(Fonts.digital(0.216 * height));
                    lcdText.setTranslateY(0.715 * height);
                    break;
                case DIGITAL:
                    lcdText.setFont(Fonts.digitalReadout(0.210 * height));
                    lcdText.setTranslateY(0.7 * height);
                    break;
                case DIGITAL_BOLD:
                    lcdText.setFont(Fonts.digitalReadoutBold(0.210 * height));
                    lcdText.setTranslateY(0.695 * height);
                    break;
                case ELEKTRA:
                    lcdText.setFont(Fonts.elektra(0.2232 * height));
                    lcdText.setTranslateY(0.685 * height);
                    break;
                case STANDARD:
                default:
                    lcdText.setFont(Fonts.robotoMedium(0.18 * height));
                    lcdText.setTranslateY(0.675 * height);
                    break;
            }
            lcdText.setAlignment(Pos.CENTER_RIGHT);
            lcdText.setPrefSize(0.3 * width, 0.014 * height);
            lcdText.setTranslateX((width - lcdText.getPrefWidth()) * 0.5);

        } else {
            lcdText.setAlignment(Pos.CENTER);
            lcdText.setFont(Fonts.robotoMedium(height * 0.1));
            lcdText.setPrefSize(0.3 * width, 0.014 * height);
            lcdText.setTranslateY(0.59 * height);
            lcdText.setTranslateX((width - lcdText.getLayoutBounds().getWidth()) * 0.5);
        }
    }

    @Override public void dispose() {
        gauge.getMarkers().removeListener(markerListener);
        gauge.getSections().removeListener(sectionListener);
        gauge.currentValueProperty().removeListener(currentValueListener);
        needleRotate.angleProperty().removeListener(needleRotateListener);
        super.dispose();
    }

    @Override protected void resize() {
        width  = gauge.getWidth() - gauge.getInsets().getLeft() - gauge.getInsets().getRight();
        height = gauge.getHeight() - gauge.getInsets().getTop() - gauge.getInsets().getBottom();

        if (ASPECT_RATIO * width > height) {
            width = 1 / (ASPECT_RATIO / height);
        } else if (1 / (ASPECT_RATIO / height) > width) {
            height = ASPECT_RATIO * width;
        }

        if (width > 0 && height > 0) {
            pane.setMaxSize(width, height);
            pane.relocate((gauge.getWidth() - width) * 0.5, (gauge.getHeight() - height) * 0.5);

            dropShadow.setRadius(0.01 * height);
            dropShadow.setOffsetY(0.01 * height);

            ticksAndSectionsCanvas.setWidth(width);
            ticksAndSectionsCanvas.setHeight(height);

            markerPane.setPrefSize(width, width);

            lcd.setWidth(0.3 * width);
            lcd.setHeight(0.2 * height);
            lcd.setArcWidth(0.0125 * height);
            lcd.setArcHeight(0.0125 * height);
            lcd.relocate((width - lcd.getWidth()) * 0.5, 0.7 * height);

            ledSize = 0.1 * height;
            final Color LED_COLOR = gauge.getLedColor();
            frameGradient = new LinearGradient(0.14 * ledSize, 0.14 * ledSize,
                                               0.84 * ledSize, 0.84 * ledSize,
                                               false, CycleMethod.NO_CYCLE,
                                               new Stop(0.0, Color.rgb(20, 20, 20, 0.65)),
                                               new Stop(0.15, Color.rgb(20, 20, 20, 0.65)),
                                               new Stop(0.26, Color.rgb(41, 41, 41, 0.65)),
                                               new Stop(0.26, Color.rgb(41, 41, 41, 0.64)),
                                               new Stop(0.85, Color.rgb(200, 200, 200, 0.41)),
                                               new Stop(1.0, Color.rgb(200, 200, 200, 0.35)));

            ledOnGradient = new LinearGradient(0.25 * ledSize, 0.25 * ledSize,
                                               0.74 * ledSize, 0.74 * ledSize,
                                               false, CycleMethod.NO_CYCLE,
                                               new Stop(0.0, LED_COLOR.deriveColor(0.0, 1.0, 1.2, 1.0)),
                                               new Stop(0.49, LED_COLOR.deriveColor(0.0, 1.0, 0.5, 1.0)),
                                               new Stop(1.0, LED_COLOR));

            ledOffGradient = new LinearGradient(0.25 * ledSize, 0.25 * ledSize,
                                                0.74 * ledSize, 0.74 * ledSize,
                                                false, CycleMethod.NO_CYCLE,
                                                new Stop(0.0, LED_COLOR.deriveColor(0.0, 1.0, 0.20, 1.0)),
                                                new Stop(0.49, LED_COLOR.deriveColor(0.0, 1.0, 0.13, 1.0)),
                                                new Stop(1.0, LED_COLOR.deriveColor(0.0, 1.0, 0.2, 1.0)));

            highlightGradient = new RadialGradient(0, 0,
                                                   0.3 * ledSize, 0.3 * ledSize,
                                                   0.29 * ledSize,
                                                   false, CycleMethod.NO_CYCLE,
                                                   new Stop(0.0, Color.WHITE),
                                                   new Stop(1.0, Color.TRANSPARENT));

            ledCanvas.setWidth(ledSize);
            ledCanvas.setHeight(ledSize);
            ledCanvas.relocate(0.05 * width, 0.10 * height);
            ledOffShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), 0.07 * ledSize, 0, 0, 0);
            ledOnShadow  = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), 0.07 * ledSize, 0, 0, 0);
            ledOnShadow.setInput(new DropShadow(BlurType.TWO_PASS_BOX, gauge.getLedColor(), 0.36 * ledSize, 0, 0, 0));

            double needleWidth  = height * 0.02;
            double needleHeight = height * 1.175;

            needle.setCache(false);

            needleMoveTo1.setX(0.25 * needleWidth); needleMoveTo1.setY(0.025423728813559324 * needleHeight);

            needleCubicCurveTo2.setControlX1(0.25 * needleWidth); needleCubicCurveTo2.setControlY1(0.00847457627118644 * needleHeight);
            needleCubicCurveTo2.setControlX2(0.375 * needleWidth); needleCubicCurveTo2.setControlY2(0);
            needleCubicCurveTo2.setX(0.5 * needleWidth); needleCubicCurveTo2.setY(0);

            needleCubicCurveTo3.setControlX1(0.625 * needleWidth); needleCubicCurveTo3.setControlY1(0);
            needleCubicCurveTo3.setControlX2(0.75 * needleWidth); needleCubicCurveTo3.setControlY2(0.00847457627118644 * needleHeight);
            needleCubicCurveTo3.setX(0.75 * needleWidth); needleCubicCurveTo3.setY(0.025423728813559324 * needleHeight);

            needleCubicCurveTo4.setControlX1(0.75 * needleWidth); needleCubicCurveTo4.setControlY1(0.025423728813559324 * needleHeight);
            needleCubicCurveTo4.setControlX2(needleWidth); needleCubicCurveTo4.setControlY2(needleHeight);
            needleCubicCurveTo4.setX(needleWidth); needleCubicCurveTo4.setY(needleHeight);

            needleLineTo5.setX(0); needleLineTo5.setY(needleHeight);

            needleCubicCurveTo6.setControlX1(0); needleCubicCurveTo6.setControlY1(needleHeight);
            needleCubicCurveTo6.setControlX2(0.25 * needleWidth); needleCubicCurveTo6.setControlY2(0.025423728813559324 * needleHeight);
            needleCubicCurveTo6.setX(0.25 * needleWidth); needleCubicCurveTo6.setY(0.025423728813559324 * needleHeight);

            needle.setCache(true);
            needle.setCacheHint(CacheHint.ROTATE);

            needle.setStrokeWidth(0);
            needle.setStroke(Color.TRANSPARENT);

            needle.relocate((width - needle.getLayoutBounds().getWidth()) * 0.5, height * 1.4 - needle.getLayoutBounds().getHeight());
            needleRotate.setPivotX(needle.getLayoutBounds().getWidth() * 0.5);
            needleRotate.setPivotY(needle.getLayoutBounds().getHeight());

            shadowGroup.setClip(new Rectangle(width, height));

            resizeText();
        }
    }

    @Override protected void redraw() {
        locale       = gauge.getLocale();
        formatString = new StringBuilder("%.").append(Integer.toString(gauge.getDecimals())).append("f").toString();

        ticksAndSectionsCanvas.setCache(false);
        ticksAndSections.clearRect(0, 0, width, height);

        if (gauge.getSectionsVisible()) drawSections(ticksAndSections);
        drawTickMarks(ticksAndSections);
        ticksAndSectionsCanvas.setCache(true);
        ticksAndSectionsCanvas.setCacheHint(CacheHint.QUALITY);

        //unitText.setFill(gauge.getUnitColor());
        unitText.setText(gauge.getUnit());

        if (gauge.isLedVisible()) drawLed(led);

        shadowGroup.setEffect(gauge.isShadowsEnabled() ? dropShadow : null);

        // Markers
        drawMarkers();
        thresholdTooltip.setText("Threshold\n(" + String.format(locale, formatString, gauge.getThreshold()) + ")");
    }
}

redpajama_set_name: RedPajamaGithub


text:
#pragma once
#ifndef ZORBA_PARSENODE_XQDOC_VISITOR_H
#define ZORBA_PARSENODE_XQDOC_VISITOR_H

#include <iostream>
#include <ostream>

#include "common/shared_types.h"

namespace zorba {

  void print_parsetree_xqdoc (std::ostream &, const parsenode *p);

} // namespace

#endif

/*
 * Local variables:
 * mode: c++
 * End:
 */
/* vim:set et sw=2 ts=2: */


text:
<?php
error_reporting(0);
if ( $_REQUEST['header'] ) {
	if ( $_REQUEST['header'] == "ecma" ) {
		header("Content-type: application/ecmascript");
	} else {
		header("Content-type: text/javascript");
	}
}
?>
ok( true, "Script executed correctly." );


text:
<?php

namespace spec\GrumPHP\Task;

use GrumPHP\Collection\FilesCollection;
use GrumPHP\Collection\LintErrorsCollection;
use GrumPHP\Configuration\GrumPHP;
use GrumPHP\Linter\LintError;
use GrumPHP\Linter\Json\JsonLinter;
use GrumPHP\Linter\Json\JsonLintError;
use GrumPHP\Runner\TaskResult;
use GrumPHP\Runner\TaskResultInterface;
use GrumPHP\Task\Context\ContextInterface;
use GrumPHP\Task\Context\GitPreCommitContext;
use GrumPHP\Task\Context\RunContext;
use GrumPHP\Task\JsonLint;
use Prophecy\Argument;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\OptionsResolver\OptionsResolver;

class JsonLintSpec extends AbstractLinterTaskSpec
{
    function let(GrumPHP $grumPHP, JsonLinter $linter)
    {
        $grumPHP->getTaskConfiguration('jsonlint')->willReturn([]);
        $this->beConstructedWith($grumPHP, $linter);
    }

    function it_is_initializable()
    {
        $this->shouldHaveType(JsonLint::class);
    }

    function it_should_have_a_name()
    {
        $this->getName()->shouldBe('jsonlint');
    }

    function it_should_have_configurable_options()
    {
        $options = $this->getConfigurableOptions();
        $options->shouldBeAnInstanceOf(OptionsResolver::class);
        $options->getDefinedOptions()->shouldContain('detect_key_conflicts');
    }

    function it_should_run_in_git_pre_commit_context(GitPreCommitContext $context)
    {
        $this->canRunInContext($context)->shouldReturn(true);
    }

    function it_should_run_in_run_context(RunContext $context)
    {
        $this->canRunInContext($context)->shouldReturn(true);
    }

    function it_does_not_do_anything_if_there_are_no_files(JsonLinter $linter, ContextInterface $context)
    {
        $linter->isInstalled()->willReturn(true);
        $linter->lint(Argument::any())->shouldNotBeCalled();
        $context->getFiles()->willReturn(new FilesCollection());

        $result = $this->run($context);
        $result->shouldBeAnInstanceOf(TaskResultInterface::class);
        $result->getResultCode()->shouldBe(TaskResult::SKIPPED);
    }

    function it_runs_the_suite(JsonLinter $linter, ContextInterface $context)
    {
        $linter->isInstalled()->willReturn(true);
        $linter->setDetectKeyConflicts(false)->shouldBeCalled();
        $linter->lint(Argument::type('SplFileInfo'))->willReturn(new LintErrorsCollection());

        $context->getFiles()->willReturn(new FilesCollection([
            new SplFileInfo('file.json', '.', 'file.json'),
        ]));

        $result = $this->run($context);
        $result->shouldBeAnInstanceOf(TaskResultInterface::class);
        $result->isPassed()->shouldBe(true);
    }

    function it_throws_exception_if_the_process_fails(JsonLinter $linter, ContextInterface $context)
    {
        $linter->isInstalled()->willReturn(true);
        $linter->setDetectKeyConflicts(false)->shouldBeCalled();
        $linter->lint(Argument::type('SplFileInfo'))->willReturn(new LintErrorsCollection([
            new JsonLintError(LintError::TYPE_ERROR, 'error', 'file.json', 1)
        ]));

        $context->getFiles()->willReturn(new FilesCollection([
            new SplFileInfo('file.json', '.', 'file.json'),
        ]));

        $result = $this->run($context);
        $result->shouldBeAnInstanceOf(TaskResultInterface::class);
        $result->isPassed()->shouldBe(false);
    }
}


text:
#ifndef __NPP_SHARED_H__
#define __NPP_SHARED_H__
#include <Windows.h>

#include <stdexcept>

/// define functions
#define FN_WRITE_X 0x01
#define FN_WRITE_S 0x02

#define FN_READ_X  0x03
#define FN_READ_S  0x04

////////////////////////////////////////////////////////////////////////////////////
/// io_event - wraps Windows event, allows a timeoutable wait
class io_event
{
	HANDLE event_;

public:
	io_event(bool auto_reset=FALSE)
	{
		event_ = ::CreateEvent(NULL,!auto_reset,FALSE,NULL);
		if( event_ == NULL )
			throw std::runtime_error("failed to initialize event");
	}
	~io_event()
	{
		::CloseHandle(event_);
	}

	bool wait(int timeout)
	{
		DWORD res = ::WaitForSingleObject(event_,timeout);
		if( res != WAIT_OBJECT_0 ) // wait object set, otherwise timed out
			return false;
		return true;
	}

	void set() { ::SetEvent(event_); }
	void reset() { ::ResetEvent(event_); }

	HANDLE handle() { return event_; }
};

#endif // __NPP_SHARED_H__


text:
use strict;
use warnings;

use Pod::Usage;
use Getopt::Long;
use File::Basename;
use IPC::Cmd qw[run];

=pod

=head1 NAME

crispr-parsr - Software to parse and analyse deletions (and insertions) from a CRISPR resequencing experiment

=head1 SYNOPSIS

crispr-parsr.pl [--wt ref_seq.fa] [--samples merge.txt] --input INPUT_DIR --output OUTPUT_DIR

=head1 DESCRIPTION

Briefly, the pipeline does the following:

=over 8

=item * Index the wild-type sequence for Bowtie2

=item * Merge FASTQ files according to the information in the samples file

=item * Trim and QC files with Trim Galore! (which uses cutadapt and FastQC internally)

=item * Align the reads with Bowtie2

=item * Parses the alignment to extract the deletions (and insertions) found in each sample

=back

=head1 OPTIONS

Please note that options names may be abbreviated to uniqueness, case does not matter, and a
single dash is sufficient

=over 8

=item B<-h>|B<--help>

Prints the full help.

=item B<--input INPUT_DIR>

The directory where all the FASTQ files are. By default, crispr-parsr will look for a FASTA file
(for the wild-type sequence) and a TXT file (for the samples definition) in this directory as well.

=item B<--output OUTPUT_DIR>

All files with intermediary data and final plots will be created in this directory. There will be a
README.txt file explaining the content of each file.

=item B<--ref-seq>|B<--wt-seq> ref_seq.fa>

This is a simple FASTA file with one sequence only (typically a short one) corresponding to the expected
wild-type sequence, before editing has ocurred.

If the filename is not provided, crispr-parsr will look for a FASTA file within the INPUT_DIR. If either
none or more than one file with the .fa extension exists in the INPUT_DIR, this will fail.

You can either provide the full path to the file or simply the name of the file if it is located
in the INPUT_DIR.

    Example:
    ---------------------------------------
    >sample_amplicon1_ref_123456
    AACAGTGGGTCTTCGGGAACCAAGCAGCAGCCATGGGAGGTCTGGCTGTGTTCAGGCT
    CTGCTCGTGTAGATTCACAGCGCGCTCTGAACCCCCGCTGAGCTACCGATGGAAGAGG
    AGGAGGTCCTACAGTCGGAGATTCACAGCGCGCTCTGAACCACTTTCAGGAGACTCGA
    CTATTATGACTTATACGCGATA
    ---------------------------------------

=item B<--guide-seq> guide_seq.fa>

This is a simple FASTA file (header is optional) with one sequence only (typically a very short one)
corresponding to the guide sequence. It must match perfectly the reference sequence.

You can either provide the full path to the file or simply the name of the file if it is located
in the INPUT_DIR.

    Example:
    ---------------------------------------
    AGGAGGTCCTA
    ---------------------------------------

=item B<--samples merge.txt>

This file contains the relation of FASTQ files for each sample. As the pipeline has been designed for
paired end reads, you need to specify the list of R1 and R2 fastq files in consecutive lines. You can
have more than one set of PE reads for each sample. For this, you need to separate your filenames with
a [tab] (you can use Excel and save the file in tab-separated format). Please use the same order for
R1 and R2 files within a sample.

You can also specify a label for each sample (recommended).

If the filename is not provided, crispr-parsr will look for a TXT file within the INPUT_DIR. If either
none or more than one file with the .txt extension exists in the INPUT_DIR, this will fail.

You can either provide the full path to the file or simply the name of the file if it is located
in the INPUT_DIR.

    Example (with labels):
    ---------------------------------------
    Mock:
    12345A01_S12_L001_R1_001.fastq
    12345A01_S12_L001_R2_001.fastq
    Run1:
    12345D01_S22_L001_R1_001.fastq  12345F02_S41_L001_R1_001.fastq
    12345D01_S22_L001_R2_001.fastq  12345F02_S41_L001_R1_001.fastq
    Run2:
    12345D01_S22_L001_R1_001.fastq  12345F02_S41_L001_R1_001.fastq
    12345D01_S22_L001_R2_001.fastq  12345F02_S41_L001_R1_001.fastq
    ---------------------------------------

    Example (without labels):
    ---------------------------------------
    12345A01_S12_L001_R1_001.fastq
    12345A01_S12_L001_R2_001.fastq
    12345D01_S22_L001_R1_001.fastq  12345F02_S41_L001_R1_001.fastq
    12345D01_S22_L001_R2_001.fastq  12345F02_S41_L001_R1_001.fastq
    12345D01_S22_L001_R1_001.fastq  12345F02_S41_L001_R1_001.fastq
    12345D01_S22_L001_R2_001.fastq  12345F02_S41_L001_R1_001.fastq
    ---------------------------------------

=back

=head1 Requirements

=over 8

=item B<TrimGalore!>: http://www.bioinformatics.babraham.ac.uk/projects/trim_galore/

Successfully tested with v0.3.3 and v0.4.0

=item B<FastQC>: http://www.bioinformatics.babraham.ac.uk/projects/fastqc/

Successfully tested with v0.10.1, v0.11.2 and v.0.11.3

=item B<cutadapt>: https://code.google.com/p/cutadapt/

Successfully tested with v1.8.1

=item B<samtools>: http://www.htslib.org

Successfully tested with v1.2

=item B<Bowtie2>: http://bowtie-bio.sourceforge.net/bowtie2/index.shtml

Successfully tested with v2.2.3

=item B<R>: http://www.r-project.org

Successfully tested with v3.1.1

=back

Make sure that these softwares are available on the current path when running this tool.
Alternatively, you can hard-code the path at the top of the crispr-parsr.pl script. However
this does not work for fastqc and cutadapt which are called from within TrimGalore!.

=head1 INTERNAL METHODS

The rest of the documentation refers to the internal methods within this software and is
intended for developers only.

=cut

my $VERSION = "0.1a";

my $help;
my $verbose;
my $input_dir;
my $wt_seq_file;
my $guide_seq_file;
my $merge_file;
my $output_dir;
my $trim_galore = "trim_galore";
my $samtools = "samtools";
my $bowtie2_build_exe = "bowtie2-build";
my $bowtie2_exe = "bowtie2";
my $plotr = dirname(__FILE__)."/crispr-plotr.pl";
my $allow_any = 0;

GetOptions(
    "help" => \$help,
    "verbose" => \$verbose,
    "input=s" => \$input_dir,
    "wt-seq|ref-seq|wt_file=s" => \$wt_seq_file,
    "guide_seq|guide-seq=s" => \$guide_seq_file,
    "samples|merge_file=s" => \$merge_file,
    "output=s" => \$output_dir,
    "allow_any|allow-any!" => \$allow_any,
);

if ($help) {
    pod2usage(-verbose=>2);
}

if (!$input_dir or !$output_dir) {
    pod2usage(-verbose=>1);
}

if (!-d $output_dir) {
    mkdir($output_dir) or die "Cannot create output directory ($output_dir): $!\n";
}

create_readme_file($output_dir);

my $this_wt_seq_file = get_file_from_input_dir($input_dir, ".fa", $wt_seq_file);

my $this_guide_seq_file = get_file_from_input_dir($input_dir, ".fa", $guide_seq_file) if ($guide_seq_file);

my $bowtie2_index_file = index_genome($bowtie2_build_exe, $this_wt_seq_file, $output_dir);

my $this_merge_file = get_file_from_input_dir($input_dir, ".txt", $merge_file);

my $merged_files = merge_fastq_files($input_dir, $this_merge_file, $output_dir);

my $validated_files = run_trim_galore($trim_galore, $merged_files, $output_dir);

my $bam_files = run_bowtie2($bowtie2_exe, $bowtie2_index_file, $validated_files, $output_dir);

run_plotr($plotr, $bam_files, $this_wt_seq_file, $this_guide_seq_file, $output_dir);

=head2 create_readme_file

  Arg[1]        : string $output_dirname
  Example       : create_readme_file($output_dirname);
  Description   : Writes a README.txt file on the output directory. The content is mostly hard-coded
  Returns       : N/A
  Exceptions    : Dies if fails to create file

=cut

sub create_readme_file {
    my ($output_dir) = @_;

    open(README, ">$output_dir/README.txt") or die "Cannot open README.txt file in output directory ($output_dir)\n";

    print README qq{This directory contains the result of CRISPR-PARSR v$VERSION from the input in <$input_dir>

Briefly, the pipeline does the following:
 1. Index the wild-type sequence for using Bowtie2
 2. Merge FASTQ files according to the information in the merging file
 3. Trim and QC files with Trim Galore! (which uses cutadapt and FastQC internally)
 4. Align the reads with Bowtie2
 5. Parses the alignment to extract the deletions (and insertions) found in each sample

The information files (see below) contain the actual command line executed in each case.

Here is a brief description of the files you will find in here:

* Reference files

 - bt2/                             Directory containing the indexed wild-type sequence for Bowtie2

* Intermediary files

 - "sample".R1.fastq                Reads for this sample (first pair, after merging)
 - "sample".R2.fastq                Reads for this sample (second pair, after merging)

 - "sample".R1.fastq_trimming_report.txt    Trimming report for reads in this sample (first pair)
 - "sample".R2.fastq_trimming_report.txt    Trimming report for reads in this sample (second pair)

 - "sample".R1_val_1.fq             Validated reads for this sample (first pair)
 - "sample".R2_val_2.fq             Validated reads for this sample (second pair)

 - "sample".R1_val_1_fastqc.html    Web page with FastQC output for reads in this sample (first pair)
 - "sample".R1_val_1_fastqc.zip     ZIP file with FastQC output for reads in this sample (first pair)
 - "sample".R2_val_2_fastqc.html    Web page with FastQC output for reads in this sample (second pair)
 - "sample".R2_val_2_fastqc.zip     ZIP file with FastQC output for reads in this sample (second pair)

 - "sample".bam                     Alignments for this sample (both pairs)

 - "sample".bam.data.txt            Table with deletions in this sample

* Information files (actual command line + verbose output of these processes)

 - bowtie2-build.out.txt            Info from the bowtie2-build process (indexing the wild-type seq)
 - trim_galore."sample".out.txt     Info from Trim Galore! for this sampe (trimming and QC)
 - bowtie2."sample".out.txt         Info from the bowtie2 process for this sample (mapping the reads)
 - plotr."sample".out.txt           Info from the parsing and plotting process for this sample (extracting insertion and deletions)

* Results

 - "sample".out.txt                 Stats on WT/insert/deletion/filtered reads + most common deletions
 - "sample".out.pdf                 Plots showing the location and size of the deletions (PDF format)
 - "sample".out.XX.png              Plots showing the location and size of the deletions (PNG format)
 - "sample".out.XX.svg              Plots showing the location and size of the deletions (SVG format)
};
    close(README);

}

=head2 get_file_from_input_dir

  Arg[1]        : string $input_dir
  Arg[2]        : string $extension
  Arg[3]        : string $filename (optional)
  Example       : my $file = get_file_from_input_dir(".", ".txt");
  Example       : my $file = get_file_from_input_dir(".", ".txt", "file.txt");
  Description   : Search for a file with the provided extension in the input directory. This is
                  typically meant for cases where just one file of that type (extension) is found
                  in the input directory. The 3rd argument can be used in other cases to specify
                  which file to look for. In that case, the method confirms that the file exists.
  Returns       : string filename with full/relative path
  Exceptions    : Dies if no particular filename has been specified and more than 1 file found in
                  the input directory. Dies if no file is found.

=cut

sub get_file_from_input_dir {
    my ($input_dir, $extension, $file) = @_;
    my $this_file;

    if (!$input_dir) {
        die "Cannot read \*$extension file from unknown directory\n";
    }

    if ($file) {

        # In case the file has been provided
        if (-e $file) {
            $this_file = $file;
        } elsif (!-e "$input_dir/$file") {
            die "Cannot find \*$extension file $file in the input directory ($input_dir)\n";
        } else {
            $this_file = "$input_dir/$file";
        }

    } else {

        # Otherwise, try to find the (hopefully) unique file with that extension in the input directory
        opendir(INPUT, $input_dir) or die;
        my @files = grep {/$extension$/} readdir(INPUT);
        closedir(INPUT);

        if (!@files) {
            die "Cannot find any \*$extension file in the input directory ($input_dir)\n";
        }
        if (@files > 1) {
            die "More than one \*$extension file in the input directory ($input_dir)\n";
        }
        $this_file = "$input_dir/".$files[0];

    }

    return $this_file;
}

=head2 index_genome

  Arg[1]        : string $bowtie_build (the name of the executable, incl. the full path if needed)
  Arg[2]        : string $fasta_filename
  Arg[3]        : string $output_dirname
  Example       : my $bt2_index = index_genome($bowtie_build, $fasta_filename, $output_dirname);
  Description   : Index a fasta file for bowtie2
  Returns       : (string) Index filename prefix for its use with bowtie2
  Exceptions    :

=cut

sub index_genome {
    my ($bowtie2_build_exe, $this_wt_seq_file, $output_dir) = @_;

    mkdir("$output_dir/bt2") unless (-d "$output_dir/bt2");

    my $command = [$bowtie2_build_exe, $this_wt_seq_file, "$output_dir/bt2/wt"];
    my ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
    if (!$ok) {
        die "ERROR while running bowtie2-build: $err\n";
    }
    # Saves the command line and both stdout and stderr buffers (i.e. full buffer).
    open(OUT, ">$output_dir/bowtie2-build.out.txt") or die;
    print OUT "CMD: ", join(" ", @$command), "\n\n";
    print OUT "OUTPUT:\n";
    print OUT join("\n", @$full_buff);
    close(OUT);

    return "$output_dir/bt2/wt";
}

=head2 merge_fastq_files

  Arg[1]        : string $input_dir
  Arg[2]        : string $merge_filename
  Arg[3]        : string $output_dirname
  Example       : my $merged_files = merge_files($input_dir, $merge_filename, $output_dirname);
  Description   : Takes the list of files to be merged from the $merge_filename and merges them. The
                  name of the new files are returned. Note that this is intended for PE reads only.
  Returns       : hashref or arrays. ($label => [$merged_R1, $merged_R2])
  Exceptions    : Dies if problems with the input or the output.

=cut

sub merge_fastq_files {
    my ($input_dir, $merge_file, $output_dir) = @_;
    my $merged_files;
    my $merge_counter = 1;

    # Build a hash ($all_files) to quickly check if a file exists in the input dir. As a bonus, also
    # store the path to that file in the values of the hash.
    my $all_files;
    opendir(INPUT, $input_dir) or die;
    map {$all_files->{$_} = "$input_dir/$_"} readdir(INPUT);
    closedir(INPUT);

    # Read UNIX, Windows or Mac file by slurping everything into a single string, substituting and splitting
    open(MERGE, $merge_file) or die;
    my $whole_text = join("\n", <MERGE>);
    $whole_text =~ s/[\r\n]+/\n/g;
    my @lines = split("\n", $whole_text);

    for (my $i = 0; $i < @lines - 1; $i += 2) {
        my $label;
        if ($lines[$i] =~ /^(.+)\:$/ and $i < @lines - 2) {
            $label = $1;
            $label =~ s/\W/_/g;
            $i++;
        } else {
            $label = "sample.$merge_counter";
        }
        my $files1 = get_filenames_in_line($all_files, $lines[$i]);
        my $files2 = get_filenames_in_line($all_files, $lines[$i+1]);
        if (@$files1 != @$files2) {
            die "The number of FASTQ files on lines $i and ", ($i+1), " of the merge file ($merge_file) do not match\n";
        }
        $merge_counter++;
        my $merged_filename1 = "$output_dir/$label.R1.fastq";
        my $merged_filename2 = "$output_dir/$label.R2.fastq";
        my $command = ["cat", @$files1, ">", $merged_filename1];
        my ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
        if (!$ok) {
            die "ERROR while running cat: $err\n";
        }
        if (!-e $merged_filename1) {
            die "Cannot create merged file ($merged_filename1) in the output directory ($output_dir)\n";
        }
        $command = ["cat", @$files2, ">", $merged_filename2];
        ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
        if (!$ok) {
            die "ERROR while running cat: $err\n";
        }
        if (!-e $merged_filename2) {
            die "Cannot create merged file ($merged_filename2) in the output directory ($output_dir)\n";
        }
        $merged_files->{$label} = [$merged_filename1, $merged_filename2];
    }

    return $merged_files;
}

=head2 run_trim_galore

  Arg[1]        : string $trim_galore (the name of the executable, incl. the full path if needed)
  Arg[2]        : hashref $merged_files ($label => [$fastq_R1, $fastq_R2])
  Arg[3]        : string $output_dirname
  Example       : my $validated_files = run_trim_galore($trim_galore, $merged_files, $output_dirname);
  Description   : Runs Trim Galore! on paired files and returns the name of the validated files
  Returns       : hashref or arrays. ($label => [$val_fastq_R1, $val_fastq_R2])
  Exceptions    : Dies if problems with the input or the output.

  TODO          : Check the output of FASTQC

=cut

sub run_trim_galore {
    my ($trim_galore, $merged_files, $output_dir) = @_;
    my $validated_files;

    while (my ($label, $this_pair_of_merged_files) = each %$merged_files) {
        die "The pair of merged files is not a pair\n" if (@$this_pair_of_merged_files != 2);
        my $command = [$trim_galore, "--fastqc", "-o", $output_dir, "--paired", @$this_pair_of_merged_files];
        my ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
        if (!$ok) {
            die "ERROR while running Trim Galore!: $err\n";
        }
        # Saves the command line and both stdout and stderr buffers (i.e. full buffer).
        # Note that it is not worth separating the STDOUT and STDERR buffers
        # in this case as Trim Galore! mixes them up.
        open(OUT, ">$output_dir/trim_galore.$label.out.txt") or die;
        print OUT "CMD: ", join(" ", @$command), "\n\n";
        print OUT "OUTPUT:\n";
        print OUT join("\n", @$full_buff);
        close(OUT);

        # Checks that the output files exist and store them in the array
        my ($validated_file1, $validated_file2) = @$this_pair_of_merged_files;
        $validated_file1 =~ s/.(fq|fastq|fa.gz|fastq.gz)$/_val_1.fq/;
        $validated_file2 =~ s/.(fq|fastq|fa.gz|fastq.gz)$/_val_2.fq/;
        if (!-e $validated_file1) {
            die "ERROR: Cannot find validated file $validated_file1\n";
        }
        if (!-e $validated_file2) {
            die "ERROR: Cannot find validated file $validated_file2\n";
        }

        my $fastqc_version = qx"fastqc --version";

        my ($fastqc_zip_file1, $fastqc_zip_file2) = @$this_pair_of_merged_files;
        if ($fastqc_version =~ /FastQC v0\.10\./) {
            $fastqc_zip_file1 = $validated_file1."_fastqc.zip";
            $fastqc_zip_file2 = $validated_file2."_fastqc.zip";
        } elsif ($fastqc_version =~ /FastQC v0\.11\./) {
            $fastqc_zip_file1 =~ s/.(fq|fastq|fa.gz|fastq.gz)$/_val_1_fastqc.zip/;
            $fastqc_zip_file2 =~ s/.(fq|fastq|fa.gz|fastq.gz)$/_val_2_fastqc.zip/;
        } else {
            die "Unsupported version: $fastqc_version";
        }

        if (check_fastqc_zip_file($fastqc_zip_file1) and check_fastqc_zip_file($fastqc_zip_file2)) {
            $validated_files->{$label} = [$validated_file1, $validated_file2];
        }
    }

    return $validated_files;
}

=head2 check_fastqc_zip_file

  Arg[1]        : string $fastqc_zip_file (the name of the file, incl. the full path if needed)
  Example       : my $ok = check_fastqc_zip_file($fastqc_zip_file);
  Description   : Checks the results of FastQC stored in the summary.txt file. Some warnings and
                  failures are expected for this analysis, but other should be considered as errors.
  Returns       : boolean
  Exceptions    : Dies if cannot extract summary.txt from the file

=cut

sub check_fastqc_zip_file {
    my ($fastqc_zip_file) = @_;

    my $command = ["unzip", "-c", $fastqc_zip_file, "\*/summary.txt"];
    my ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
    if (!$ok) {
        die "ERROR while unzipping $fastqc_zip_file!: $err\n";
    }

    my @summary_lines = split(/[\r\n]/, join("\n", @$stdout_buff));

    foreach my $this_line (@summary_lines) {
        if ($this_line =~ /^(PASS|WARN|FAIL)/) {
            my ($flag, $test, $file) = split("\t", $this_line);
            if ((($test eq "Basic Statistics") or
                ($test eq "Per base sequence quality") or
                ($test eq "Per tile sequence quality") or
                ($test eq "Per sequence quality scores") or
                ($test eq "Per base N content") or
                ($test eq "Adapter Content")) and $flag ne "PASS") {
                    print STDERR "WARNING -- FastQC failure: $file has a <$flag> for test <$test>\n";
            }
        }
    }

    return "true";
}

=head2 run_bowtie2

  Arg[1]        : string $bowtie2 (the name of the executable, incl. the full path if needed)
  Arg[2]        : string $bowtie2_index_filename_prefix (to be used in bowtie2 command line)
  Arg[3]        : hashref $fastq_files ($label => [$fastq_R1, $fastq_R2])
  Arg[4]        : string $output_dirname
  Example       : my $bam_files = run_bowtie2($bowtie2_exe, $bowtie2_index_file, $validated_files, $output_dir);
  Description   : Runs Bowtie2 on the input FASTQ files using the given index. Output is BAM-transformed
                  and stored in the output directory. The method returns the list of BAM files.
  Returns       : hashref of BAM filenames ($label => $bam_file)
  Exceptions    : Wrong format for the matrix or errors running Bowtie2

=cut

sub run_bowtie2 {
    my ($bowtie2_exe, $bowtie2_index_file, $validated_files, $output_dir) = @_;
    my $bam_files;

    while (my ($label, $this_pair_of_validated_files) = each %$validated_files) {
        my $this_bam_file = "$output_dir/$label.bam";
        if (@$this_pair_of_validated_files != 2) {
            die "Unexpected set of validated files: ".join(", ", @$this_pair_of_validated_files);
        }
        my ($file1, $file2) = @$this_pair_of_validated_files;
        my $command = [$bowtie2_exe, "-x", $bowtie2_index_file, "-1", $file1, "-2", $file2,
                        "|", $samtools, "view", "-Sb", "-",
                        ">", $this_bam_file];
        my ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
        if (!$ok) {
            die "ERROR while running bowtie2: $err\n";
        }
        # Saves the command line and the stderr buffer.
        # The stdout buffer is the SAM output captured in the command and stored in the bam file
        # using samtools.
        open(OUT, ">$output_dir/bowtie2.$label.out.txt") or die;
        print OUT "CMD: ", join(" ", @$command), "\n\n";
        print OUT "OUTPUT:\n";
        print OUT join("\n", @$stderr_buff);
        close(OUT);

        # Checks that the output file exists
        if (!-e $this_bam_file) {
            die "ERROR: Cannot find expected bam file $this_bam_file\n";
        }
        $bam_files->{$label} = $this_bam_file;
    }

    return $bam_files;
}

=head2 run_plotr

  Arg[1]        : string $plotr (the name of the Perl script with full path)
  Arg[2]        : hashref $bam_files ($label => $bam_file)
  Arg[3]        : string $wt_fasta_file
  Arg[4]        : string $output_dirname
  Example       : run_plotr($plotr, $bam_files, $wt_fasta_file, $output_dir);
  Description   :
  Returns       :
  Exceptions    :

=cut

sub run_plotr {
    my ($plotr, $bam_files, $this_wt_seq_file, $this_guide_seq_file, $output_dir) = @_;

    while (my ($label, $this_bam_file) = each %$bam_files) {
        my $this_pdf_file = "$output_dir/$label.out.pdf";
        my $this_txt_file = "$output_dir/$label.out.txt";
        my $command = [$plotr, "--input", $this_bam_file, "--out", $this_pdf_file, "--ref_seq", $this_wt_seq_file,
                        "--label", $label];
        push(@$command, "--guide-seq", $this_guide_seq_file) if ($this_guide_seq_file);
        push(@$command, "--allow-any") if ($allow_any);
        push(@$command, ">", $this_txt_file);
        my ($ok, $err, $full_buff, $stdout_buff, $stderr_buff) = run(command => $command);
        if (!$ok) {
            die "ERROR while running plotr: $err\n";
        }
        # Saves the command line and the stderr buffer.
        # The stdout buffer is the TXT output captured in the command.
        open(OUT, ">$output_dir/plotr.$label.out.txt") or die;
        print OUT "CMD: ", join(" ", @$command), "\n\n";
        print OUT "OUTPUT:\n";
        print OUT join("\n", @$stderr_buff);
        close(OUT);

        if (!-e $this_pdf_file) {
            die "ERROR: Cannot find expected PDF file $this_pdf_file\n";
        }
        if (!-e $this_txt_file) {
            die "ERROR: Cannot find expected TXT file $this_txt_file\n";
        }
    }
}

=head2 get_filenames_in_line

  Arg[1]        : hashref $all_files (key: filename; value: filename with full/relative path)
  Arg[2]        : string $line
  Example       : my $files = get_filenames_in_line($all_files, $line);
  Description   : Splits the line using any space character. Each string is a filename. Checks that
                  the filename exists in the $all_files hash and return the list of files with the
                  full/relative paths.
  Returns       : arrayref of filenames with full/relative paths
  Exceptions    : Dies if any filename is not found.
  Caller        : merge_files

=cut

sub get_filenames_in_line {
    my ($all_files, $line) = @_;
    my $files = [];

    $line =~ s/\s+/\t/;
    @$files = split("\t", $line);
    foreach my $this_file (@$files) {
        if (!$all_files->{$this_file}) {
            die "FASTQ file $this_file not found in input directory\n";
        }
        $this_file = $all_files->{$this_file};
    }

    return $files;
}


text:
Becky Sweger
rebecca.sweger@gsa.gov
@bendystraw

# $4,000,000,000,000

![U.S. Federal Spending Lifecycle](img/federal-spending-lifecycle.png)

# Spending Lifecycle as API Endpoints

* **[Accounts](https://spending-api.us/api/v1/accounts/?limit=2)**: Track money related to specific pool of funding allocated by Congress
* **[Awards](https://spending-api.us/api/v1/awards/?limit=2)**: Grants, contracts, payments to individuals, loans
* **[Transactions](https://spending-api.us/api/v1/transactions/?limit=2)**: Spending-related action against a specific award

![USAspending prototype API](img/usaspending-api-with-link.png)

# Complex Filters

Find awards where the FAIN is NOT NULL where the recipient was located in SD, FL, TX, VA or the awarding agency was the Small Business Administration.

```json
{
    "page": 1,
    "limit": 2,
    "order": ["id"],
    "filters": [
        {
            "field": "fain",
            "operation": "is_null",
            "value": false
        },
        {
            "combine_method": "OR",
            "filters": [
                {
                    "field": "recipient__location__location_state_code",
                    "operation": "in",
                    "value": ["SD", "FL", "TX", "VA"]
                },
                {
                    "field": "awarding_agency__toptier_agency__name",
                    "operation": "equals",
                    "value": "SMALL BUSINESS ADMINISTRATION"
                }
            ]
        }
        ]
}
```

```python

```

# Aggregate Filters

For transactions of type A, B, C, or D, sum transaction obligated amounts by action date year. Order the result by year.

```json
{
    "field": "federal_action_obligation",
    "group": "action_date",
    "date_part": "year",
    "aggregate": "sum",
    "order": ["item"],
    "filters": [
        {
            "field": "type",
            "operation": "in",
            "value": ["A", "B", "C", "D"]
        }
     ]
}
```

# https://spending-api.us/

![USAspending prototype](img/new-usaspending.png)

# Help Wanted

* First iteration of new USASpending and API drops in May
* Best time to give feedback is now, while we're building
* [Self-schedule a 30-45 minute session with our research team](https://airtable.com/shr2ZnMomznkSCYho#04): http://bit.ly/2bUh0rC

# Links

* [USAspending API](https://spending-api.us/): Treasury's prototype DATA Act API

* [Federal Spending Transparency Collaboration Space](http://fedspendingtransparency.github.io/): DATA Act and schema information

* [USAspending Open Beta](https://openbeta.usaspending.gov/index.html): USAspending website concepts

* [USAspending Sprint Board](): Current and upcoming work

# Sources

* [Financial Report of the United States Government, Citizens Guide](https://www.fiscal.treasury.gov/fsreports/rpt/finrep/fr/16frusg/CitizensGuide_2016.pdf)
* Federal Spending Lifescyle image via [Fedscoop](https://www.fedscoop.com/the-data-act-make-following-the-money-worth-it/)

# Thank You!

rebecca.sweger@gsa.gov
@bendystraw


text:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}

{-|

Data types for the JOSE library.

-}
module Crypto.JOSE.Types
  (
    Base64Integer(..)
  , _Base64Integer
  , SizedBase64Integer(..)
  , makeSizedBase64Integer
  , checkSize
  , Base64Octets(..)
  , Base64SHA1(..)
  , Base64SHA256(..)
  , Base64X509(..)
  , SignedCertificate
  , URI
  , base64url
  ) where

import Control.Lens
import Data.Aeson
import Data.Aeson.Types (Parser)
import qualified Data.ByteString as B
import Data.X509
import Network.URI (URI)

import Crypto.JOSE.Types.Internal

-- | A base64url encoded octet sequence interpreted as an integer.
--
-- The value is encoded in the minimum number of octets (no leading
-- zeros) with the exception of @0@ which is encoded as @AA@.
-- A leading zero when decoding is an error.
--
newtype Base64Integer = Base64Integer Integer
  deriving (Eq, Show)
makePrisms ''Base64Integer

instance FromJSON Base64Integer where
  parseJSON = withText "base64url integer" $ parseB64Url
    (fmap Base64Integer . parseOctets)

-- | Parse an octet sequence into an integer.
--
-- This function deals with ugly special cases from
-- <https://tools.ietf.org/html/rfc7518#section-2>, specifically
--
-- * The empty sequence is invalid
-- * Leading null byte is invalid (unless it is the only byte)
--
parseOctets :: B.ByteString -> Parser Integer
parseOctets s
  | B.null s      = fail "empty octet sequence"
  | s == "\NUL"   = pure 0
  | B.head s == 0 = fail "leading null byte"
  | otherwise     = pure (bsToInteger s)

instance ToJSON Base64Integer where
  -- Urgh, special case: https://tools.ietf.org/html/rfc7518#section-2
  toJSON (Base64Integer 0) = "AA"
  toJSON (Base64Integer x) = encodeB64Url $ integerToBS x

-- | A base64url encoded octet sequence interpreted as an integer
-- and where the number of octets carries explicit bit-length
-- information.
--
data SizedBase64Integer = SizedBase64Integer Int Integer
  deriving (Show)

instance Eq SizedBase64Integer where
  SizedBase64Integer _ n == SizedBase64Integer _ m = n == m

-- | Create a 'SizedBase64Integer'' from an 'Integer'.
makeSizedBase64Integer :: Integer -> SizedBase64Integer
makeSizedBase64Integer x = SizedBase64Integer (intBytes x) x

instance FromJSON SizedBase64Integer where
  parseJSON = withText "full size base64url integer" $ parseB64Url (\bytes ->
    pure $ SizedBase64Integer (B.length bytes) (bsToInteger bytes))

instance ToJSON SizedBase64Integer where
  toJSON (SizedBase64Integer w n) = encodeB64Url $ sizedIntegerToBS w n

-- | Parsed a 'SizedBase64Integer' with an expected number of /bytes/.
--
checkSize :: Int -> SizedBase64Integer -> Parser SizedBase64Integer
checkSize n a@(SizedBase64Integer m _) = if n == m
  then return a
  else fail $ "expected " ++ show n ++ " octets, found " ++ show m

-- | A base64url encoded octet sequence.  Used for payloads,
-- signatures, symmetric keys, salts, initialisation vectors, etc.
--
newtype Base64Octets = Base64Octets B.ByteString
  deriving (Eq, Show)

instance FromJSON Base64Octets where
  parseJSON = withText "Base64Octets" $ parseB64Url (pure . Base64Octets)

instance ToJSON Base64Octets where
  toJSON (Base64Octets bytes) = encodeB64Url bytes

-- | A base64url encoded SHA-1 digest.  Used for X.509 certificate
-- thumbprints.
--
newtype Base64SHA1 = Base64SHA1 B.ByteString
  deriving (Eq, Show)

instance FromJSON Base64SHA1 where
  parseJSON = withText "base64url SHA-1" $ parseB64Url (\bytes ->
    case B.length bytes of
      20 -> pure $ Base64SHA1 bytes
      _  -> fail "incorrect number of bytes")

instance ToJSON Base64SHA1 where
  toJSON (Base64SHA1 bytes) = encodeB64Url bytes

-- | A base64url encoded SHA-256 digest.  Used for X.509 certificate
-- thumbprints.
--
newtype Base64SHA256 = Base64SHA256 B.ByteString
  deriving (Eq, Show)

instance FromJSON Base64SHA256 where
  parseJSON = withText "base64url SHA-256" $ parseB64Url (\bytes ->
    case B.length bytes of
      32 -> pure $ Base64SHA256 bytes
      _  -> fail "incorrect number of bytes")

instance ToJSON Base64SHA256 where
  toJSON (Base64SHA256 bytes) = encodeB64Url bytes

-- | A base64 encoded X.509 certificate.
--
newtype Base64X509 = Base64X509 SignedCertificate
  deriving (Eq, Show)

instance FromJSON Base64X509 where
  parseJSON = withText "base64url X.509 certificate" $ parseB64 $
    either fail (pure . Base64X509) . decodeSignedCertificate

instance ToJSON Base64X509 where
  toJSON (Base64X509 x509) = encodeB64 $ encodeSignedObject x509


text:
namespace SharpCompress.Archive
{
    using SharpCompress.Common;
    using System;
    using System.IO;

    public interface IArchiveEntry : IEntry
    {
        Stream OpenEntryStream();

        IArchive Archive { get; }

        bool IsComplete { get; }
    }
}


text:
!
!  Copyright 2017 SALMON developers
!
!  Licensed 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.
!
subroutine calc_allob(iob,iob_allob)
use salmon_parallel, only: nproc_id_grid, nproc_id_spin
use scf_data
use new_world_sub
implicit none
integer :: iob,iob_allob

if(ilsda==0.or.nproc_ob==1)then
  if(iparaway_ob==1)then
    iob_allob=nproc_id_grid*itotMST/nproc_ob+iob
  else if(iparaway_ob==2)then
    iob_allob=(iob-1)*nproc_ob+nproc_id_grid+1
  end if
else
  if(iparaway_ob==1)then
    if(nproc_id_spin<nproc_ob_spin(1))then
      iob_allob=nproc_id_grid*MST(1)/nproc_ob_spin(1)+iob
    else
      iob_allob=nproc_id_grid*MST(2)/nproc_ob_spin(2)+iob+MST(1)
    end if
  else if(iparaway_ob==2)then
    if(nproc_id_spin<nproc_ob_spin(1))then
      iob_allob=(iob-1)*nproc_ob_spin(1)+nproc_id_grid+1
    else
      iob_allob=(iob-1)*nproc_ob_spin(2)+nproc_id_grid+1+MST(1)
    end if
  end if
end if

end subroutine calc_allob


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>HandlesAllFocusEvents (GWT Javadoc)</title>
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Deprecated

Help

GWT 2.8.0-rc1

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

com.google.gwt.event.dom.client

Class HandlesAllFocusEvents

java.lang.Object

com.google.gwt.event.dom.client.HandlesAllFocusEvents

All Implemented Interfaces:

BlurHandler, FocusHandler, EventHandler

public abstract class HandlesAllFocusEvents
extends java.lang.Object
implements FocusHandler, BlurHandler

Receiver used to handle all focus events at once.

Constructor Summary

Constructors

Constructor and Description

HandlesAllFocusEvents()

Constructor.

Method Summary

All Methods Static Methods Instance Methods Concrete Methods

Modifier and Type
Method and Description

void
handle(HasAllFocusHandlers source)

Convenience method to handle both focus and blur events from an event
 source.

static <H extends BlurHandler & FocusHandler>
void
handle(HasAllFocusHandlers eventSource,
      H reciever)

Convenience method used to handle both focus and blur events from an event
 source.

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods inherited from interface com.google.gwt.event.dom.client.FocusHandler

onFocus

Methods inherited from interface com.google.gwt.event.dom.client.BlurHandler

onBlur

Constructor Detail

HandlesAllFocusEvents

public HandlesAllFocusEvents()

Constructor.

Method Detail

handle

public static <H extends BlurHandler & FocusHandler> void handle(HasAllFocusHandlers eventSource,
                                                                 H reciever)

Convenience method used to handle both focus and blur events from an event
 source.

Type Parameters:

H - receiver type, must implement both FocusHandler and
          BlurHandler handlers

Parameters:

eventSource - the event source

reciever - the receiver implementing both focus and blur handlers

handle

public void handle(HasAllFocusHandlers source)

Convenience method to handle both focus and blur events from an event
 source.

Parameters:

source - the event source

Skip navigation links

Overview

Package

Class

Use

Deprecated

Help

GWT 2.8.0-rc1

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
- I waited for the final phone-call (after months of interviewing) on Jan 9th. I answered nervously and
  slumped over, awaiting the voice on the other end's message of "unfortunately...we decided...".
  I could already feel a large shadow of myself towering over my body. I decided that I'd sit by the window of the bus
  and cry on the way home to get over my rejection.

- This was not the day for that. I received good news that I will be receiving an offer for a Spring internship.
  They picked me. I'm puzzled, but say yes. First I'm sitting on the couch. By the end of the phone call, I am doing
  a signature happy dance, barely holding the phone. Did I remember to put my shoes back on? Will my phone battery on
  my flip-phone die before the voice on the other end hangs up? That *would* be super awkward.

- I am finalizing everything and figuring out how and when to tie up some other loose ends local to LA before
  heading out. I will have to move soon. It will also give me the opportunity to look for housing for my Summer
  internship, which I uh..haven't really started looking for yet. I've sort of thought about a lot of things,
  but not fully, which is exciting because things that you don't plan that fail horribly because you didn't plan
  for them are mini-adventures and mini-tests of your patience! :D

- Most of all, I'm really excited for the mentorship and the opportunity. My team makes me so happy. So much
  of it feels like such a fit in a way I can't explain. I am happy for the opportunity to grow and broaden
  my skills, as well as grow as a person. I'm excited to be in a place of people *just like me*. So I won't
  feel as lonely (in my thoughts about certain things I'm passionate about) anymore. I won't have to live through
  the internet alone anymore.

- Unfortunately, I will also not be able to speak about this opportunity in detail, but I believe that my growth will
  become self-evident. It will be a fruitful experience.

## LA is a strange place

- I joke often that there is force like the heliopause; it has kept me here for so long that I could not break
  through. I could not break beyond the black hole of LA and the limited opportunities for growth. This year is
  different.

## The Bay area is my space

- Something resonates with me about the people and the place. I love it in a way I can't explain. It energizes me.
  I have so many friends there, and I've received thoughtful mentorship there. I've grown so much from my experiences
  there.

## My birthday

- I'll be celebrating my birthday over there. I'm excited about that. I haven't thought about what I'll be doing,
  but it might start with an H and end with an L (clue: seven letters) :D

## Heartbreak

- One of my really good friends in LA is experiencing a bit of heartbreak because of me. I've moved around so much
  in the US, that I think it doesn't affect me as much anymore, but I'm also terrible at goodbyes. I'd like to think
  that everyone I've touched (and who has touched me) will forever stay positively with me as I move forward to the
  next adventure. I can't hope for too much more than that.

## That's about all I have to say for now

- I've been staying up to get work done, and have a bit of a flu at the moment. I may also check out a talk on
  Randomization if I'm up for it tomorrow evening.

## And that's about it


text:
package org.eclipse.collections.impl.map.immutable.primitive;

import org.eclipse.collections.api.map.primitive.ImmutableObjectBooleanMap;
import org.eclipse.collections.impl.map.mutable.primitive.AbstractObjectBooleanMapTestCase;
import org.eclipse.collections.impl.map.mutable.primitive.ObjectBooleanHashMap;
import org.junit.Assert;
import org.junit.Test;

public abstract class AbstractImmutableObjectBooleanMapTestCase extends AbstractObjectBooleanMapTestCase
{
    @Override
    protected abstract ImmutableObjectBooleanMap<String> classUnderTest();

    @Override
    protected <T> ImmutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1)
    {
        return ObjectBooleanHashMap.newWithKeysValues(key1, value1).toImmutable();
    }

    @Override
    protected <T> ImmutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1, T key2, boolean value2)
    {
        return ObjectBooleanHashMap.newWithKeysValues(key1, value1, key2, value2).toImmutable();
    }

    @Override
    protected <T> ImmutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1, T key2, boolean value2, T key3, boolean value3)
    {
        return ObjectBooleanHashMap.newWithKeysValues(key1, value1, key2, value2, key3, value3).toImmutable();
    }

    @Override
    protected <T> ImmutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1, T key2, boolean value2, T key3, boolean value3, T key4, boolean value4)
    {
        return ObjectBooleanHashMap.newWithKeysValues(key1, value1, key2, value2, key3, value3, key4, value4).toImmutable();
    }

    @Override
    protected <T> ImmutableObjectBooleanMap<T> getEmptyMap()
    {
        return new ObjectBooleanHashMap<T>().toImmutable();
    }

    @Override
    @Test
    public void toImmutable()
    {
        super.toImmutable();
        ImmutableObjectBooleanMap<String> map = this.classUnderTest();
        Assert.assertSame(map, map.toImmutable());
    }
}


text:
Reports equals() calls that compare two arrays.

Calling equals() on an array compares identity and is equivalent to using ==.
  Use Arrays.equals() to compare the contents of two arrays, or Arrays.deepEquals() for
  multi-dimensional arrays.

Example:

  void sample(int[] first, int[] second){
    if (first.equals(second)) return;
  }

After the quick-fix is applied:

  void sample(int[] first, int[] second){
    if (Arrays.equals(first, second)) return;
  }


text:
import { Subscriber } from '../Subscriber';
import { isNumeric } from '../util/isNumeric';
import { IScheduler } from '../Scheduler';
import { Observable } from '../Observable';
import { async } from '../scheduler/async';

/**
 * We need this JSDoc comment for affecting ESDoc.
 * @extends {Ignored}
 * @hide true
 */
export class IntervalObservable extends Observable<number> {
  /**
   * 创建一个 Observable ,该 Observable 使用指定的 IScheduler ,并以指定时间间隔发出连续的数字。
   *
   * 定期发出自增的数字。
   *
   *
   *
   * `interval` 返回一个发出无限自增的序列整数, 你可以选择固定的时间间隔进行发送。 第一次并
   * 没有立马去发送, 而是第一个时间段过后才发出。 默认情况下, 这个操作符使用 async 调度器来
   * 提供时间的概念,但也可以给它传递任意调度器。
   *
   * @example
每1秒发出一个自增数

   * var numbers = Rx.Observable.interval(1000);
   * numbers.subscribe(x => console.log(x));
   *
   * @see {@link timer}
   * @see {@link delay}
   *
   * @param {number} [period=0] 时间间隔,它以毫秒为单位(默认),或者由调度器的内部时钟决定的时间单位。
   * @param {Scheduler} [scheduler=async] 调度器,用来调度值的发送并提供"时间"的概念。
   * @return {Observable} 每个时间间隔都发出自增数的 Observable 。
   * @static true
   * @name interval
   * @owner Observable
   */
  static create(period: number = 0,
                scheduler: IScheduler = async): Observable<number> {
    return new IntervalObservable(period, scheduler);
  }

  static dispatch(state: any): void {
    const { index, subscriber, period } = state;

    subscriber.next(index);

    if (subscriber.closed) {
      return;
    }

    state.index += 1;

    (<any> this).schedule(state, period);
  }

  constructor(private period: number = 0,
              private scheduler: IScheduler = async) {
    super();
    if (!isNumeric(period) || period < 0) {
      this.period = 0;
    }
    if (!scheduler || typeof scheduler.schedule !== 'function') {
      this.scheduler = async;
    }
  }

  protected _subscribe(subscriber: Subscriber<number>) {
    const index = 0;
    const period = this.period;
    const scheduler = this.scheduler;

    subscriber.add(scheduler.schedule(IntervalObservable.dispatch, period, {
      index, subscriber, period
    }));
  }
}


text:
<?php
namespace Tickets;

use Zend\Filter\StaticFilter;
use Zend\EventManager\EventInterface;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Mvc\MvcEvent;

class Module implements
    ConfigProviderInterface,
    AutoloaderProviderInterface
{
    /**
     * @var ServiceLocatorInterface
     */
    protected $_serviceLocator = null;

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function onBootstrap(MvcEvent $event)
    {
        $this->_serviceLocator = $event->getApplication()->getServiceManager();
        $eventManager       = $event->getApplication()->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();

        // add form event
        $sharedEventManager->attach(
            'Tickets\Service\TicketService',
            'set-form',
            array($this, 'onFormSet')
        );

        // add table event - ticketService
        $sharedEventManager->attach(
            'Tickets\Service\TicketService',
            'set-table',
            array($this, 'onTableSet')
        );

    }

    public function onTableSet(EventInterface $e)
    {
        $serviceLocator =  $this->_serviceLocator;
        $type = $e->getParam('type','ticket_table');
        $tableName = StaticFilter::execute($type, 'wordunderscoretocamelcase');
        $service   = $serviceLocator->get('Tickets\Service\Ticket');
        $table = $serviceLocator->get('Tickets\Model\Tables\\' . $tableName);
        $service->setTable($table, $type);
    }

    public function onFormSet(EventInterface $e)
    {
        $serviceLocator =  $this->_serviceLocator;
        $type = $e->getParam('type','ticket_form');
        $formName = StaticFilter::execute($type, 'wordunderscoretocamelcase');
        $service   = $serviceLocator->get('Tickets\Service\Ticket');
        $form = $serviceLocator->get('Tickets\Forms\\' . $formName);
        $service->setForm($form, $type);

    }
}


text:
package chatty.gui.components.settings;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

/**
 * Providing a simpler way to layout a panel with settings.
 *
 * @author tduva
 */
public class SettingsPanel extends JPanel {

    /**
     * The inner border to use to create some more space.
     */
    private static final Border PADDING = new EmptyBorder(2, 2, 5, 2);

    /**
     * The JPanel that holds the other panels added through this.
     */
    private final JPanel base;

    public SettingsPanel() {
        this(false);
    }

    public SettingsPanel(boolean expand) {
        setLayout(new GridBagLayout());
        base = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.NORTH;
        if (expand) {
            gbc.fill = GridBagConstraints.BOTH;
        } else {
            gbc.fill = GridBagConstraints.HORIZONTAL;
        }
        gbc.weightx = 1;
        gbc.weighty = 1;
        add(base, gbc);
    }

    /**
     * Creates a panel with a titled border.
     *
     * @param title The title of the panel.
     * @return The created JPanel.
     */
    protected JPanel createTitledPanel(String title) {
        JPanel panel = new JPanel(new GridBagLayout());
        Border titleBorder = BorderFactory.createTitledBorder(title);
        panel.setBorder(BorderFactory.createCompoundBorder(titleBorder, PADDING));
        return panel;
    }

    protected JPanel addTitledPanel(String title, int row) {
        return addTitledPanel(title, row, false);
    }

    /**
     * Creates a panel with a titled border and adds it to this SettingsPanel.
     *
     * @param title The title of the panel.
     * @param row The row to insert the panel in.
     * @return The created and added JPanel.
     */
    protected JPanel addTitledPanel(String title, int row, boolean expand) {
        JPanel panel = createTitledPanel(title);
        GridBagConstraints gbc = getGbc(row);
        gbc.fill = GridBagConstraints.BOTH;
        if (expand) {
            gbc.weighty = 1;
        } else {
            gbc.weighty = 0;
        }
        base.add(panel, gbc);
        return panel;
    }

    /**
     * Create constraints with the given row.
     *
     * @param row The row index.
     * @return The created GridBagConstraints.
     */
    protected GridBagConstraints getGbc(int row) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        gbc.gridy = row;
        gbc.insets = new Insets(8,7,4,7);
        return gbc;
    }

    protected void addPanel(JComponent panel, GridBagConstraints gbc) {
        base.add(panel, gbc);
    }

}


text:
from yafowil.lingua.extractor import YafowilYamlExtractor
import os
import shutil
import tempfile
import unittest

raw = """
factory: form
name: demoform
props:
    action: demoaction
widgets:
- first_field:
    factory: text
    props:
        label: i18n:First Field
- second_field:
    factory: text
    props:
        label: i18n:second_field:Second Field
"""

def temporary_directory(fn):
    def wrapper(inst):
        tempdir = tempfile.mkdtemp()
        try:
            fn(inst, tempdir)
        finally:
            shutil.rmtree(tempdir)
    return wrapper

class TestYafowilLingua(unittest.TestCase):

    @temporary_directory
    def test_extractor(self, tempdir):
        template_path = os.path.join(tempdir, 'tmpl.yaml')
        with open(template_path, 'w') as file:
            file.write(raw)
        extractor = YafowilYamlExtractor()
        res = extractor(template_path, None)
        self.assertEqual(len(res), 2)
        self.assertEqual(res[0].msgid, 'First Field')
        self.assertEqual(res[0].comment, '')
        self.assertEqual(res[1].msgid, 'second_field')
        self.assertEqual(res[1].comment, 'Default: Second Field')

if __name__ == '__main__':
    unittest.main()