text:
var SDT = (function() {
    //初始化SVG画布
    if (document.querySelector(".sdt-canvas #sdtDropCanvas")) {
        document.querySelector(".sdt-canvas #sdtDropCanvas").innerHTML = document.querySelector(".sdt-canvas #sdtDropCanvas").innerHTML + '<g id="sdtDropCanvasAll"><g id="sdtDropCanvasRight"></g><g id="sdtDropCanvasLeft"></g></g>';
        document.querySelector(".sdt-canvas #sdtDropCanvas #sdtDropCanvasAll").setAttribute("style", "-moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none;");
    }
    //配置单
    var SDTTreeCollocated = {
        "SDTTreeElements": [],
        "SDTTreeSet": {
            "SDTTreeLineType": "bessel", //元素连线方式 bessel,straight
            "SDTTreeEleHeight": 0, // 元素的 height
            "SDTTreeEleWidth": 0, // 元素的 width
            "SDTTreeEleMargin": 0, //元素的边距
            "SDTTreeLineColor": "#000", // 连线的颜色
            "SDTTreeCenterX": 0, // 树的中心点坐标 X
            "SDTTreeCenterY": 0, // 树的中心点坐标 Y
            "SDTViewBoxMinX": 0, //sdtDropCanvas 的 viewBox
            "SDTViewBoxMinY": 0, //sdtDropCanvas 的 viewBox
            "SDTViewBoxWidth": 0, //sdtDropCanvas 的 viewBox
            "SDTViewBoxHeight": 0 //sdtDropCanvas 的 viewBox
        }
    };
    //临时元素对象,用作事件间的信息传递
    var provisionalSDTTreeEle;
    //元素放置顺序表
    var eleSeqList = [];
    //右边树
    var SDTTreeRight = {
            "id": "SDTTreeRight",
            "objHeight": 0,
            "childEles": [],
            "objRelativelyHeight": 0,
            "objcolumn": 0
        }
        //左边树
    var SDTTreeLeft = {
            "id": "SDTTreeLeft",
            "objHeight": 0,
            "childEles": [],
            "objRelativelyHeight": 0,
            "objcolumn": 0
        }
        //树
    var SDTTree = {
            "id": "SDTTree",
            "objHeight": 0,
            "childEles": [SDTTreeRight, SDTTreeLeft],
            "objRelativelyHeight": 0,
            "objcolumn": 0
        }
        // 元素类型计数表
    var typeEleCountList = [];

    var dropError = {};
    dropError.dataDropError;

    // 颜色值测试正则表达式子
    var pattern = new RegExp(/^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/);
    // 是否第一次放置的标记
    var firstDrop = true;
    //元素构造函数
    function SDTTreeEle() {
        this.type = ""; //元素类型
        this.dropSwitch = true; //元素是否可放置状态的开关
        this.foresideType = []; //元素可以放在哪些元素后
        this.id = ""; //元素ID,不可变,唯一
        this.name = ""; //元素名,可变
        this.foresideObjId = ""; //当前元素的上层元素的ID
        this.objHeight = 1; //元素占高
        this.childEles = []; //子元素
        this.objRelativelyHeight = 0; //元素相对高度
        this.objcolumn = 0; //元素列数
        this.leanRight = true; //元素是否默认放置与右边
    }
    //元素类型对象构造函数
    function TypeEleCount(countType) {
        this.countType = countType;
        this.countNumber = 0;
    }

    // 获取可拖动元素
    if (document.querySelectorAll(".sdt-drag-element")) {
        // 可拖动元素配置
        var sdtList = document.querySelectorAll(".sdt-drag-element");
        for (var i = 0; i < sdtList.length; i++) {
            if (sdtList[i].dataset.sdtType) {
                sdtList[i].setAttribute("draggable", "true");
                var SDTTreeEleObj = {
                    "dropSwitch": true, // 元素默认可放置
                    "foresideType": ["all"], // 元素默认可放置于所有元素后
                    "objHeight": 1, // 元素占高
                    "leanRight": true
                }
                SDTTreeEleObj.type = sdtList[i].dataset.sdtType;
                // 从HTML读取配置并设置
                if (sdtList[i].dataset.sdtElesetDropswitch) {
                    if (sdtList[i].dataset.sdtElesetDropswitch === "ture") {
                        SDTTreeEleObj.dropSwitch = true;
                    } else {
                        SDTTreeEleObj.dropSwitch = false;
                    }
                }
                if (sdtList[i].dataset.sdtElesetForesidetype) {
                    SDTTreeEleObj.foresideType = [];
                    var ForesidetypeStr = "";
                    var sdtElesetForesidetypeSrt = sdtList[i].dataset.sdtElesetForesidetype;
                    for (j = 0; j < sdtElesetForesidetypeSrt.length; j++) {
                        if (sdtElesetForesidetypeSrt.charAt(j) !== ",") {
                            ForesidetypeStr = ForesidetypeStr + sdtElesetForesidetypeSrt.charAt(j);
                        } else {
                            SDTTreeEleObj.foresideType.push(ForesidetypeStr);
                            ForesidetypeStr = "";
                        };
                        if (j === sdtElesetForesidetypeSrt.length - 1) {
                            SDTTreeEleObj.foresideType.push(ForesidetypeStr);
                            ForesidetypeStr = "";
                        }
                    }
                }
                if (sdtList[i].dataset.sdtElesetLeanright) {
                    if (sdtList[i].dataset.sdtElesetLeanright === "ture") {
                        SDTTreeEleObj.leanRight = true;
                    } else {
                        SDTTreeEleObj.leanRight = false;
                    }
                }
                if (sdtList[i].getElementsByTagName("text")[0]) {
                    SDTTreeEleObj.name = sdtList[i].getElementsByTagName("text")[0].childNodes[0].nodeValue;
                }
                SDTTreeCollocated.SDTTreeElements.push(SDTTreeEleObj);
                // 元素类型计数表添加新类型
                var eleCount = new TypeEleCount(SDTTreeEleObj.type);
                typeEleCountList.push(eleCount);
            }
        }
        // 元素的 width 和 height设置
        SDTTreeCollocated.SDTTreeSet.SDTTreeEleWidth = document.querySelector(".sdt-drag-element svg").width.baseVal.value;
        SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight = document.querySelector(".sdt-drag-element svg").height.baseVal.value;
        SDTTreeCollocated.SDTTreeSet.SDTViewBoxWidth = document.querySelector(".sdt-canvas").clientWidth;
        SDTTreeCollocated.SDTTreeSet.SDTViewBoxHeight = document.querySelector(".sdt-canvas").clientHeight;
        // 画布配置
        var sCanvas = document.querySelector(".sdt-canvas");
        if (sCanvas.dataset.sdtElesetLinetype) {
            SDTTreeCollocated.SDTTreeSet.SDTTreeLineType = sCanvas.dataset.sdtElesetLinetype;
        }
        if (sCanvas.dataset.sdtElesetLinecolor) {
            if (pattern.test(sCanvas.dataset.sdtElesetLinecolor)) {
                SDTTreeCollocated.SDTTreeSet.SDTTreeLineColor = sCanvas.dataset.sdtElesetLinecolor;
            } else {
                console.log("颜色值非法");
            }
        }
        if (sCanvas.dataset.sdtElesetTreecenterx) {
            SDTTreeCollocated.SDTTreeSet.SDTTreeCenterX = Number(sCanvas.dataset.sdtElesetTreecenterx);
        }
        if (sCanvas.dataset.sdtElesetTreecentery) {
            SDTTreeCollocated.SDTTreeSet.SDTTreeCenterY = Number(sCanvas.dataset.sdtElesetTreecentery);
        };
        if (sCanvas.dataset.sdtElesetMargin) {
            SDTTreeCollocated.SDTTreeSet.SDTTreeEleMargin = Number(sCanvas.dataset.sdtElesetMargin);
            SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight = SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight + SDTTreeCollocated.SDTTreeSet.SDTTreeEleMargin;
        } else {
            SDTTreeCollocated.SDTTreeSet.SDTTreeEleMargin = SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight;
            SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight = SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight + SDTTreeCollocated.SDTTreeSet.SDTTreeEleMargin;
        }
    }

    document.querySelector(".sdt-drag-element-lis").ondragstart = function(event) { //监听 .sdt-drag-element-lis 上的拖拽开始事件 dragstart
        var type;
        if (event.target.dataset.sdtType) {
            type = event.target.dataset.sdtType;
            provisionalSDTTreeEle = creatSDTTreeEle(type); //创建当前 type 类型的对象,并由 provisionalSDTTreeEle 保存
        }
        event.dataTransfer.setData("Text", provisionalSDTTreeEle); //事件传递信息设为 provisionalSDTTreeEle
    }
    document.getElementById("sdtDropCanvas").ondragover = function(event) { //设置画布"sdtDropCanvas"允许放置,阻止对元素的默认处理方式
        event.preventDefault();
    }
    document.getElementById("sdtDropCanvas").ondrop = function(event) { //监听画布 "sdtDropCanvas" 的 ondrop 放置事件,阻止对元素的默认处理方式(打开链接)
        event.preventDefault();
        if (provisionalSDTTreeEle) {
            if (provisionalSDTTreeEle.dropSwitch === true) { //如果临时对象的dropSwitch属性为
                typeEleCountList.forEach(function(element) {
                    if (element.countType === provisionalSDTTreeEle.type) {
                        provisionalSDTTreeEle.id = provisionalSDTTreeEle.type + (element.countNumber + 1);
                        if (provisionalSDTTreeEle.name === "") {
                            provisionalSDTTreeEle.name = provisionalSDTTreeEle.id;
                        } else {
                            provisionalSDTTreeEle.name = provisionalSDTTreeEle.name + "-" + (element.countNumber + 1);
                        }
                        element.countNumber++;
                    }
                });
                if (event.target.id === "sdtDropCanvas") {
                    if (provisionalSDTTreeEle.leanRight) {
                        provisionalSDTTreeEle.foresideObjId = "SDTTreeRight"; //设置元素与上层元素ID
                    } else {
                        provisionalSDTTreeEle.foresideObjId = "SDTTreeLeft";
                    }
                } else {
                    provisionalSDTTreeEle.foresideObjId = event.target.parentNode.id;
                }
                // 设置列
                if (event.target.parentNode.getAttribute("objcolumn")) {
                    provisionalSDTTreeEle.objcolumn = Number(event.target.parentNode.getAttribute("objcolumn")) + 1;
                } else {
                    provisionalSDTTreeEle.objcolumn = 1;
                }
                pushObject(SDTTree, provisionalSDTTreeEle);
                eleSeqList.push(provisionalSDTTreeEle.id);
                canvasRepain();
            } else {
                dropError.dataDropError = provisionalSDTTreeEle.foresideType;
            }
        }
        provisionalSDTTreeEle = null;
    }

    function creatSDTTreeEle(type) { //创建特定type类型的对象
        var typeObj;
        SDTTreeCollocated.SDTTreeElements.forEach(function(element) {
            if (element.type === type) {
                typeObj = new SDTTreeEle();
                typeObj.type = element.type;
                typeObj.name = element.name;
                typeObj.dropSwitch = element.dropSwitch;
                typeObj.foresideType = element.foresideType;
                typeObj.leanRight = element.leanRight;
            }
        });
        return typeObj;
    }

    function canvasRepain() {
        setObjHeight(SDTTree);
        //清空画布
        document.querySelectorAll("#sdtDropCanvasRight svg,#sdtDropCanvasLeft svg,.objLine").forEach(function(element) {
            element.remove();
        });
        draw(SDTTree, SDTTreeCollocated.SDTTreeSet);
        if (SDTTreeCollocated.SDTTreeSet.SDTTreeLineType === "straight") {
            linkObjStraight(SDTTree, SDTTreeCollocated.SDTTreeSet);
        } else {
            linkObjBessel(SDTTree, SDTTreeCollocated.SDTTreeSet);
        }
        //对画布上的所有元素绑定事件
        setDropObject();
        // 初次放置后的画布行为初始化
        if (firstDrop) {
            canvasBlow();
            dragable();
            firstDrop = false;
        }
    }

    function pushObject(rootObj, obj) {
        for (var i = 0; i < rootObj.childEles.length; i++) {
            if (rootObj.childEles[i].id === obj.id) {
                obj.foresideObjId = null;
            } else {
                pushObject(rootObj.childEles[i], obj);
                if (rootObj.childEles[i].id === obj.foresideObjId) {
                    rootObj.childEles[i].childEles.push(obj);
                }
            }
        }
    }

    function removeObject(rootObj, obj) {
        for (var i = 0; i < rootObj.childEles.length; i++) {
            removeObject(rootObj.childEles[i], obj);
            if (rootObj.childEles[i].id === obj) {
                rootObj.childEles.splice(i, 1);
            }
        }
    }

    function setObjHeight(obj) {
        insetobjHeight(obj.childEles[0]);
        insetobjHeight(obj.childEles[1]);

        function insetobjHeight(setHiObj) {
            if (setHiObj.childEles.length > 0) {
                setHiObj.objHeight = 0;
            };
            for (var i = 0; i < setHiObj.childEles.length; i++) {

                insetobjHeight(setHiObj.childEles[i]);
                setHiObj.objHeight = setHiObj.objHeight + setHiObj.childEles[i].objHeight;
                setHiObj.childEles[i].objRelativelyHeight = setHiObj.childEles[i].objHeight;
            }
        }
    }

    function draw(obj, ts) {
        var eleHi = ts.SDTTreeEleHeight;
        var eleWi = ts.SDTTreeEleWidth;
        var eleMar = ts.SDTTreeEleMargin;
        var cenX = ts.SDTTreeCenterX;
        var cenY = ts.SDTTreeCenterY;
        drawEle(obj.childEles[0], true);
        drawEle(obj.childEles[1], false);

        function drawEle(drawObj, rightOn) {
            for (var i = 0; i < drawObj.childEles.length; i++) {
                drawObj.childEles[i].objRelativelyHeight = ((drawObj.childEles.length > 1) ? ((i > 0) ? drawObj.childEles[i].objRelativelyHeight * 0.5 + drawObj.childEles[i - 1].objRelativelyHeight + drawObj.childEles[i - 1].objHeight * 0.5 : drawObj.objRelativelyHeight + drawObj.childEles[i].objRelativelyHeight * 0.5 - drawObj.objHeight * 0.5) : drawObj.objRelativelyHeight);
                var dropDeviceObject = document.querySelector("[data-sdt-type=" + drawObj.childEles[i].type + "] svg").cloneNode(true);
                dropDeviceObject.setAttribute("id", drawObj.childEles[i].id);
                dropDeviceObject.setAttribute("class", drawObj.childEles[i].type);
                dropDeviceObject.setAttribute("objcolumn", drawObj.childEles[i].objcolumn);
                if (rightOn) {
                    dropDeviceObject.setAttribute("x", (((eleHi * 3) + eleWi) * drawObj.childEles[i].objcolumn) - eleWi + cenX);
                } else {
                    dropDeviceObject.setAttribute("x", -((eleHi * 3) + eleWi) * drawObj.childEles[i].objcolumn + cenX);
                }
                dropDeviceObject.setAttribute("y", eleHi * (drawObj.childEles[i].objRelativelyHeight) + eleMar / 2 + cenY);
                if (rightOn) {
                    document.querySelector("#sdtDropCanvasRight").appendChild(dropDeviceObject);
                } else {
                    document.querySelector("#sdtDropCanvasLeft").appendChild(dropDeviceObject);
                }
                document.querySelector("#" + drawObj.childEles[i].id + " text").childNodes[0].nodeValue = drawObj.childEles[i].name;
                drawEle(drawObj.childEles[i], rightOn);
            }
        }
    }

    function linkObjStraight(obj, ls) {
        var eleHi = ls.SDTTreeEleHeight;
        var eleWi = ls.SDTTreeEleWidth;
        var lineColor = ls.SDTTreeLineColor;
        var cenX = ls.SDTTreeCenterX;
        var cenY = ls.SDTTreeCenterY;
        sLinkObj(obj.childEles[0], true);
        sLinkObj(obj.childEles[1], false);

        function sLinkObj(lObj, rightOn) {
            for (var i = 0; i < lObj.childEles.length; i++) {
                sLinkObj(lObj.childEles[i], rightOn);
                if (rightOn) {
                    var x1 = ((eleHi * 3) + eleWi) * lObj.childEles[i].objcolumn - (eleHi * 3) - eleWi + cenX;
                    var srtH = " h ";
                } else {
                    var x1 = -((eleHi * 3) + eleWi) * lObj.childEles[i].objcolumn + ((eleHi * 3) + eleWi) + cenX;
                    var srtH = " h -";
                }
                var y1 = eleHi * (lObj.childEles[i].objRelativelyHeight) - ((lObj.childEles[i].objHeight > 1) ? (lObj.childEles[i].objHeight - 1) * (eleHi / 2) : 0);
                y1 = y1 + cenY;
                var y2 = eleHi + ((lObj.childEles[i].objHeight > 1) ? (lObj.childEles[i].objHeight - 1) * eleHi : 0);
                var y3 = -(eleHi / 2) - ((lObj.childEles[i].objHeight > 1) ? (lObj.childEles[i].objHeight - 1) * (eleHi / 2) : 0);

                if (lObj.childEles.length > 1) {
                    if (i === 0) {
                        document.getElementById("sdtDropCanvasAll").innerHTML = document.getElementById("sdtDropCanvasAll").innerHTML + "<path class='objLine' d =' M " + x1 + " " + (y1 + y2 + y3) + srtH + (eleHi * 3) + "' stroke = '" + lineColor + "' fill='transparent'/><path class='objLine' d =' M " + x1 + " " + (y1 + y2 + y3 - (eleHi / 4)) + " v " + (-y3 + (eleHi / 4)) + "' stroke = '" + lineColor + "' stroke-width='4px' fill='transparent'/>";
                    } else if (i === (lObj.childEles.length - 1)) {
                        document.getElementById("sdtDropCanvasAll").innerHTML = document.getElementById("sdtDropCanvasAll").innerHTML + "<path class='objLine' d =' M " + x1 + " " + (y1 + y2 + y3) + srtH + (eleHi * 3) + "' stroke = '" + lineColor + "' fill='transparent'/><path class='objLine' d =' M " + x1 + " " + y1 + " v " + (y2 + y3 + (eleHi / 2 / 2)) + "' stroke = '" + lineColor + "' stroke-width='4px' fill='transparent'/>";
                    } else {
                        document.getElementById("sdtDropCanvasAll").innerHTML = document.getElementById("sdtDropCanvasAll").innerHTML + "<path class='objLine' d =' M " + x1 + " " + (y1 + y2 + y3) + srtH + (eleHi * 3) + "' stroke = '" + lineColor + "' fill='transparent'/><path class='objLine' d =' M " + x1 + " " + y1 + " v " + y2 + "' stroke = '" + lineColor + "' stroke-width='4px' fill='transparent'/>";
                    };
                } else {
                    y1 = y1 + (eleHi / 4);
                    y2 = y2 - (eleHi / 2);
                    y3 = y3 + (eleHi / 4);
                    document.getElementById("sdtDropCanvasAll").innerHTML = document.getElementById("sdtDropCanvasAll").innerHTML + "<path class='objLine' d =' M " + x1 + " " + (y1 + y2 + y3) + srtH + (eleHi * 3) + "' stroke = '" + lineColor + "' fill='transparent'/><path class='objLine' d =' M " + x1 + " " + y1 + " v " + y2 + "' stroke = '" + lineColor + "' stroke-width='4px' fill='transparent'/>";
                }
            }
        }
    }

    function linkObjBessel(obj, ls) {
        var eleHi = ls.SDTTreeEleHeight;
        var eleWi = ls.SDTTreeEleWidth;
        var lineColor = ls.SDTTreeLineColor;
        var cenX = ls.SDTTreeCenterX;
        var cenY = ls.SDTTreeCenterY;
        bLinkObj(obj.childEles[0], true);
        bLinkObj(obj.childEles[1], false);

        function bLinkObj(lObj, rightOn) {
            for (var i = 0; i < lObj.childEles.length; i++) {
                bLinkObj(lObj.childEles[i], rightOn);
                if (rightOn) {
                    var x1 = ((eleHi * 3) + eleWi) * lObj.childEles[i].objcolumn - eleWi + cenX;
                    var x2 = ((eleHi * 3) + eleWi) * lObj.objcolumn + eleWi - eleWi + eleHi + cenX;
                    var cx1 = x1 - eleHi;
                    var cx2 = x2 - eleHi;
                } else {
                    var x1 = -((eleHi * 3) + eleWi) * lObj.childEles[i].objcolumn + eleWi + cenX;
                    var x2 = x1 + (eleHi * 3) - eleHi;
                    var cx1 = x1 + eleHi;
                    var cx2 = x2 + eleHi;
                }
                var y1 = eleHi * (lObj.childEles[i].objRelativelyHeight) + (eleHi / 2) + cenY;
                var y2 = eleHi * (lObj.objRelativelyHeight) + (eleHi / 2) + cenY;
                document.getElementById("sdtDropCanvasAll").innerHTML = document.getElementById("sdtDropCanvasAll").innerHTML + "<path class='objLine' d =' M " + x1 + " " + y1 + " C " + cx1 + " " + y1 + "," + x2 + " " + y2 + "," + cx2 + " " + y2 + "' stroke = '" + lineColor + "' fill='transparent'/>";
            }
        }
    }

    function setDropObject() { //将所有画布上的元素绑定事件
        document.querySelectorAll("#sdtDropCanvas svg").forEach(function(element) {
            element.ondragover = function(event) {
                event.preventDefault();
                if (provisionalSDTTreeEle) {
                    var parentClass = this.getAttribute("class");
                    var fTypes = provisionalSDTTreeEle.foresideType
                    if (fTypes.indexOf(parentClass) !== -1 || fTypes.indexOf("all") !== -1) {
                        event.target.parentNode.setAttribute('opacity', 0.38);
                        provisionalSDTTreeEle.dropSwitch = true;
                    } else {
                        provisionalSDTTreeEle.dropSwitch = false;
                    }

                }
            };
            element.ondragleave = function(event) {
                event.preventDefault();
                this.setAttribute('opacity', 1);
                provisionalSDTTreeEle.dropSwitch = false;
                var fTypes = provisionalSDTTreeEle.foresideType
                if (fTypes.indexOf("root") !== -1 || fTypes.indexOf("all") !== -1) {
                    provisionalSDTTreeEle.dropSwitch = true;
                }
            }
        });
    }

    function dragable() {
        var dragCanvasSVG = document.querySelector("#sdtDropCanvas");

        function dragableMousemove(event) {
            SDTTreeCollocated.SDTTreeSet.SDTViewBoxMinX = (-(event.clientX - x));
            SDTTreeCollocated.SDTTreeSet.SDTViewBoxMinY = (-(event.clientY - y));
            dragCanvasSVG.setAttribute("viewBox", SDTTreeCollocated.SDTTreeSet.SDTViewBoxMinX + "," + SDTTreeCollocated.SDTTreeSet.SDTViewBoxMinY + "," + SDTTreeCollocated.SDTTreeSet.SDTViewBoxWidth + "," + SDTTreeCollocated.SDTTreeSet.SDTViewBoxHeight);
        }

        function dragableCount(event) {
            x = (event.clientX + SDTTreeCollocated.SDTTreeSet.SDTViewBoxMinX);
            y = (event.clientY + SDTTreeCollocated.SDTTreeSet.SDTViewBoxMinY);

            document.addEventListener("mousemove", dragableMousemove);
        }
        document.getElementById('sdtDropCanvas').addEventListener("mousedown", dragableCount, false);
        document.addEventListener("mouseup", function(event) {
            document.removeEventListener("mousemove", dragableMousemove);
        });
        document.addEventListener("dragend", function(event) {
            document.removeEventListener("mousemove", dragableMousemove);
        });
    }

    function canvasBlow() {
        var SDTViewBoxHeight = SDTTreeCollocated.SDTTreeSet.SDTViewBoxHeight;
        var sdtDropCanvasScale = 1;
        document.querySelector("#sdtDropCanvas").addEventListener("mousewheel", function(event) {
            event.preventDefault();
            if (event.wheelDelta > 0) {
                if (sdtDropCanvasScale < 1.5) {
                    sdtDropCanvasScale += 0.1;
                }
            } else {
                if (sdtDropCanvasScale > 0.75) {
                    sdtDropCanvasScale -= 0.1;
                }
            }
            document.getElementById("sdtDropCanvasAll").setAttribute("transform", "translate(" + (SDTViewBoxHeight / 2) + " " + (SDTViewBoxHeight / 2) + ") scale(" + sdtDropCanvasScale + ") translate(" + -(SDTViewBoxHeight / 2) + " " + -(SDTViewBoxHeight / 2) + ")");
        });

        document.querySelector("#sdtDropCanvas").addEventListener("DOMMouseScroll", function(event) {
            event.preventDefault();
            if (event.detail < 0) {
                if (sdtDropCanvasScale < 1.5) {
                    sdtDropCanvasScale += 0.1;
                };
            } else {
                if (sdtDropCanvasScale > 0.75) {
                    sdtDropCanvasScale -= 0.1;
                };
            };
            document.getElementById("sdtDropCanvasAll").setAttribute("transform", "translate(" + (SDTViewBoxHeight / 2) + " " + (SDTViewBoxHeight / 2) + ") scale(" + sdtDropCanvasScale + ") translate(" + -(SDTViewBoxHeight / 2) + " " + -(SDTViewBoxHeight / 2) + ")");
        });
    }

    return {
        SVGDragComponent: function(_component) {
            if (_component.SDTTreeSet.lineType) {
                SDTTreeCollocated.SDTTreeSet.SDTTreeLineType = _component.SDTTreeSet.lineType;
            }
            if (_component.SDTTreeSet.lineColor) {
                if (pattern.test(_component.SDTTreeSet.lineColor)) {
                    SDTTreeCollocated.SDTTreeSet.SDTTreeLineColor = _component.SDTTreeSet.lineColor;
                } else {
                    console.log("颜色值非法");
                }
            }
            if (_component.SDTTreeSet.treeCenterX !== undefined) {
                SDTTreeCollocated.SDTTreeSet.SDTTreeCenterX = Number(_component.SDTTreeSet.treeCenterX);
            }
            if (_component.SDTTreeSet.treeCenterY !== undefined) {
                SDTTreeCollocated.SDTTreeSet.SDTTreeCenterY = Number(_component.SDTTreeSet.treeCenterY);
            }
            if (_component.SDTTreeSet.treeEleMargin !== undefined) {
                SDTTreeCollocated.SDTTreeSet.SDTTreeEleMargin = Number(_component.SDTTreeSet.treeEleMargin);
                SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight = document.querySelector(".sdt-drag-element svg").height.baseVal.value;
                SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight = SDTTreeCollocated.SDTTreeSet.SDTTreeEleHeight + SDTTreeCollocated.SDTTreeSet.SDTTreeEleMargin;
            }
            _component.SDTTreeElements.forEach(function(element) {
                var _comEle = element;
                SDTTreeCollocated.SDTTreeElements.forEach(function(element) {
                    if (_comEle.type === element.type) {
                        if ("dropSwitch" in _comEle) {
                            if (typeof _comEle.dropSwitch === "string") {
                                if (_comEle.dropSwitch === "ture") {
                                    element.dropSwitch = true;
                                } else {
                                    element.dropSwitch = false;
                                }
                            } else if (typeof _comEle.dropSwitch === "boolean") {
                                element.dropSwitch = _comEle.dropSwitch;
                            };
                        };
                        if ("foresideType" in _comEle) {
                            element.foresideType = _comEle.foresideType;
                        };
                        if ("leanRight" in _comEle) {
                            element.leanRight = _comEle.leanRight;
                        };
                        if ("name" in _comEle) {
                            element.name = _comEle.name;
                        }
                    }
                });
            });
        },
        returnTree: function(simplify) {
            if (simplify) {
                var simplifySDTTree = simplifyTree(SDTTree);

                function simplifyTree(rawTree, sTree) {
                    var sTree = sTree || {};
                    for (var i in rawTree) {
                        if (i === "id" || i === "name" || i === "foresideObjId" || i === "childEles" || !isNaN(i)) {
                            if (typeof rawTree[i] === 'object') {
                                sTree[i] = (Object.prototype.toString.call(rawTree[i]) === '[object Array]') ? [] : {};
                                simplifyTree(rawTree[i], sTree[i]);
                            } else {
                                sTree[i] = rawTree[i];
                            }
                        }
                    }
                    return sTree;
                }
                return simplifySDTTree;
            }
            var intTree = [SDTTree, eleSeqList, typeEleCountList];
            return intTree;
        },
        backCenter: function() {
            var dragSVG = document.getElementById("sdtDropCanvas");
            var cs = SDTTreeCollocated.SDTTreeSet
            var minX = cs.SDTViewBoxMinX;
            var minY = cs.SDTViewBoxMinY;
            var vbWi = cs.SDTViewBoxWidth;
            var vbHi = cs.SDTViewBoxHeight;
            setTimeout(function() {
                if (minX != 0 || minY != 0) {
                    minX = minX - minX / 4;
                    minY = minY - minY / 4;
                    if (((minX < 1) && (minX > 0)) || ((minX > -1) && (minX < 0))) {
                        minX = 0;
                    };
                    if (((minY < 1) && (minY > 0)) || ((minY > -1) && (minY < 0))) {
                        minY = 0;
                    };
                    dragSVG.setAttribute("viewBox", minX + "," + minY + "," + vbHi + "," + vbWi);
                    cs.SDTViewBoxMinX = minX;
                    cs.SDTViewBoxMinY = minY;
                    cs.SDTViewBoxWidth = vbWi;
                    cs.SDTViewBoxHeight = vbHi;
                    setTimeout(arguments.callee, 20);
                };
            }, 20);
        },
        removeELe: function(eleList) {
            if (Object.prototype.toString.call(eleList) === '[object Array]') {
                eleList.forEach(function(element) {
                    removeObject(SDTTree, element);
                });
            } else if (eleList === undefined) {
                removeObject(SDTTree, eleSeqList.pop());
            }
            canvasRepain();
        },
        drawInputTree: function(tree) {
            SDTTree = tree[0];
            eleSeqList = tree[1];
            typeEleCountList = tree[2];
            canvasRepain();
        },
        dropErrorMsg: dropError,
    };
}());


text:
namespace xls::noc {

ChannelOptionsProtoBuilder::ChannelOptionsProtoBuilder(
    ChannelOptionsProto* proto_ptr)
    : proto_ptr_(XLS_DIE_IF_NULL(proto_ptr)) {}

ChannelOptionsProtoBuilder::ChannelOptionsProtoBuilder(
    ChannelOptionsProto* proto_ptr, const ChannelOptionsProto& default_proto)
    : ChannelOptionsProtoBuilder(proto_ptr) {
  *proto_ptr_ = default_proto;
}

ChannelOptionsProtoBuilder& ChannelOptionsProtoBuilder::CopyFrom(
    const ChannelOptionsProtoBuilder& builder) {
  *proto_ptr_ = *builder.proto_ptr_;
  return *this;
}

ChannelOptionsProtoBuilder& ChannelOptionsProtoBuilder::SetSourceNodeName(
    std::string_view source_node_name) {
  proto_ptr_->set_source_node_name(xls::ToProtoString(source_node_name));
  return *this;
}

ChannelOptionsProtoBuilder& ChannelOptionsProtoBuilder::SetSinkNodeName(
    std::string_view sink_node_name) {
  proto_ptr_->set_sink_node_name(xls::ToProtoString(sink_node_name));
  return *this;
}

}  // namespace xls::noc

redpajama_set_name: RedPajamaGithub


text:
package net.engio.mbassy.bus.error;

import net.engio.mbassy.bus.IMessagePublication;

import java.lang.reflect.Method;

/**
 * Publication errors are created when object publication fails
 * for some reason and contain details as to the cause and location
 * where they occurred.
 * <p/>
 *
 * @author bennidi
 *         Date: 2/22/12
 *         Time: 4:59 PM
 */
public class PublicationError{

    // Internal state
    private Throwable cause;
    private String message;
    private Method handler;
    private Object listener;
    private Object publishedObject;

    /**
     * Compound constructor, creating a PublicationError from the supplied objects.
     *
     * @param cause           The Throwable giving rise to this PublicationError.
     * @param message         The message to send.
     * @param handler        The method where the error was created.
     * @param listener The object in which the PublicationError was generated.
     * @param publishedObject The published object which gave rise to the error.
     */
    public PublicationError(final Throwable cause,
                            final String message,
                            final Method handler,
                            final Object listener,
                            final Object publishedObject) {

        this.cause = cause;
        this.message = message;
        this.handler = handler;
        this.listener = listener;
        this.publishedObject = publishedObject;
    }

    public PublicationError(final Throwable cause,
                            final String message,
                            final IMessagePublication publication) {
        this.cause = cause;
        this.message = message;
        this.publishedObject = publication != null ? publication.getMessage() : null;
    }

    /**
     * Default constructor.
     */
    public PublicationError() {
        super();
    }

    /**
     * @return The Throwable giving rise to this PublicationError.
     */
    public Throwable getCause() {
        return cause;
    }

    /**
     * Assigns the cause of this PublicationError.
     *
     * @param cause A Throwable which gave rise to this PublicationError.
     * @return This PublicationError.
     */
    public PublicationError setCause(Throwable cause) {
        this.cause = cause;
        return this;
    }

    public String getMessage() {
        return message;
    }

    public PublicationError setMessage(String message) {
        this.message = message;
        return this;
    }

    public Method getHandler() {
        return handler;
    }

    public PublicationError setHandler(Method handler) {
        this.handler = handler;
        return this;
    }

    public Object getListener() {
        return listener;
    }

    public PublicationError setListener(Object listener) {
        this.listener = listener;
        return this;
    }

    public Object getPublishedObject() {
        return publishedObject;
    }

    public PublicationError setPublishedObject(Object publishedObject) {
        this.publishedObject = publishedObject;
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
    	String newLine = System.getProperty("line.separator");
        return "PublicationError{" +
                newLine +
                "\tcause=" + cause +
                newLine +
                "\tmessage='" + message + '\'' +
                newLine +
                "\thandler=" + handler +
                newLine +
                "\tlistener=" + listener +
                newLine +
                "\tpublishedObject=" + publishedObject +
                '}';
    }
}


text:
declare function test<T>(o: T): T;
const testRes = test({ name: 'hello', userId: 'uiui9d9f7d67sweyu' });
console.log(testRes.userId);
console.log(testRes.name);


text:
namespace DOMAIN_NAME.Business.Models

public class User{

}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ManagedLzma.LZMA
{
    public sealed class AsyncEncoder : IDisposable
    {
        #region Variables

        // immutable
        private readonly object mSyncObject;

        // multithreaded access (under lock)
        private Task mEncoderTask;
        private Task mDisposeTask;
        private bool mRunning;

        // owned by encoder task
        private Master.LZMA.CLzmaEnc mEncoder;

        #endregion

        #region Implementation

        public AsyncEncoder(EncoderSettings settings)
        {
            if (settings == null)
                throw new ArgumentNullException(nameof(settings));

            mSyncObject = new object();

            mEncoder = new Master.LZMA.CLzmaEnc();
            mEncoder.LzmaEnc_SetProps(settings.GetInternalSettings());
        }

        public void Dispose()
        {
            DisposeAsync().GetAwaiter().GetResult();
        }

        public Task DisposeAsync()
        {
            // We need to ensure that cleanup only happens once, so we need to remember that we started it.
            // We also need to make sure that the returned task completes *after* everything has been disposed.
            // Both can be covered by keeping track of the disposal via a Task object.
            //
            lock (mSyncObject)
            {
                if (mDisposeTask == null)
                {
                    if (mRunning)
                    {
                        mDisposeTask = mEncoderTask.ContinueWith(new Action<Task>(delegate {
                            lock (mSyncObject)
                                DisposeInternal();
                        }));

                        Monitor.PulseAll(mSyncObject);
                    }
                    else
                    {
                        DisposeInternal();
                        mDisposeTask = Utilities.CompletedTask;
                    }
                }

                return mDisposeTask;
            }
        }

        private void DisposeInternal()
        {
            System.Diagnostics.Debug.Assert(Monitor.IsEntered(mSyncObject));
            System.Diagnostics.Debug.Assert(!mRunning);

            // mDisposeTask may not be set yet if we complete mEncoderTask from another thread.
            // However even if mDisposeTask is not set we can be sure that the encoder is not running.

            mEncoder.LzmaEnc_Destroy(Master.LZMA.ISzAlloc.SmallAlloc, Master.LZMA.ISzAlloc.BigAlloc);
        }

        public Task EncodeAsync(IStreamReader input, IStreamWriter output, CancellationToken ct = default(CancellationToken))
        {
            lock (mSyncObject)
            {
                if (mDisposeTask != null)
                    throw new OperationCanceledException();

                // TODO: make this wait async as well
                while (mRunning)
                {
                    Monitor.Wait(mSyncObject);

                    if (mDisposeTask != null)
                        throw new OperationCanceledException();
                }

                mRunning = true;
            }

            var task = Task.Run(async delegate {
                var res = mEncoder.LzmaEnc_Encode(new AsyncOutputProvider(output), new AsyncInputProvider(input), null, Master.LZMA.ISzAlloc.SmallAlloc, Master.LZMA.ISzAlloc.BigAlloc);
                if (res != Master.LZMA.SZ_OK)
                    throw new InvalidOperationException();

                await output.CompleteAsync().ConfigureAwait(false);
            }, ct);

            mEncoderTask = task.ContinueWith(delegate {
                lock (mSyncObject)
                {
                    System.Diagnostics.Debug.Assert(mRunning);
                    mRunning = false;
                    Monitor.PulseAll(mSyncObject);
                }
            }, CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default);

            return task;
        }

        #endregion
    }
}


text:
export class AbstractKVStorage {
  // get :: String -> Promise(T)
  async get(key) {} // eslint-disable-line

  // set :: String -> T -> Promise
  async set(key, value) {} // eslint-disable-line
}


text:
namespace AdapterLib
{
    //const definitions
    static const std::wstring cVendor = L"Microsoft";
    static const std::wstring cAdapterName = L"BACnet Bridge";
    static const std::wstring cDomainPrefix = L"com";
    static const std::wstring cAdapterPrefix = cDomainPrefix + L"." + DsbCommon::ToLower(cVendor.c_str())->Data();

    //
    // BACnetAdapter class.
    // Description:
    // The class that implements the BACnet Adapter as IAdapter.
    //
    ref class BACnetInterface;
    //
    public ref class BACnetAdapter sealed
        : public BridgeRT::IAdapter,
		public IBACnetNotificationListener
    {
    public:
        //
        // Adapter information
        //
        virtual property Platform::String^ Vendor
        {
            Platform::String^ get() { return this->vendor; }
        }
        virtual property Platform::String^ AdapterName
        {
            Platform::String^ get() { return this->adapterName; }
        }
        virtual property Platform::String^ Version
        {
            Platform::String^ get() { return this->version; }
        }
        virtual property Platform::String^ ExposedAdapterPrefix
        {
            Platform::String^ get() { return this->exposedAdapterPrefix; }
        }
        virtual property Platform::String^ ExposedApplicationName
        {
            Platform::String^ get() { return this->exposedApplicationName; }
        }
        virtual property Platform::Guid ExposedApplicationGuid
        {
            Platform::Guid get() { return this->exposedApplicationGuid; }
        }

        //
        // Adapter signals
        //
        virtual property BridgeRT::IAdapterSignalVector^ Signals
        {
            BridgeRT::IAdapterSignalVector^ get() { return ref new BridgeRT::AdapterSignalVector(this->signals); }
        }

        //
        // IAdapter interface
        //
        virtual uint32 SetConfiguration(_In_ const Platform::Array<byte>^ ConfigurationData);
        virtual uint32 GetConfiguration(_Out_ Platform::Array<byte>^* ConfigurationDataPtr);

        virtual uint32 Initialize();
        virtual uint32 Shutdown();

        virtual uint32 EnumDevices(
            _In_ BridgeRT::ENUM_DEVICES_OPTIONS Options,
            _Out_ BridgeRT::IAdapterDeviceVector^* DeviceListPtr,
            _Out_opt_ BridgeRT::IAdapterIoRequest^* RequestPtr
            );

        virtual uint32 GetProperty(
            _Inout_ BridgeRT::IAdapterProperty^ Property,
            _Out_opt_ BridgeRT::IAdapterIoRequest^* RequestPtr
            );
        virtual uint32 SetProperty(
            _In_ BridgeRT::IAdapterProperty^ Property,
            _Out_opt_ BridgeRT::IAdapterIoRequest^* RequestPtr
            );

        virtual uint32 GetPropertyValue(
            _In_ BridgeRT::IAdapterProperty^ Property,
            _In_ Platform::String^ AttributeName,
            _Out_ BridgeRT::IAdapterValue^* ValuePtr,
            _Out_opt_ BridgeRT::IAdapterIoRequest^* RequestPtr
            );
        virtual uint32 SetPropertyValue(
            _In_ BridgeRT::IAdapterProperty^ Property,
            _In_ BridgeRT::IAdapterValue^ Value,
            _Out_opt_ BridgeRT::IAdapterIoRequest^* RequestPtr
            );

        virtual uint32 CallMethod(
            _Inout_ BridgeRT::IAdapterMethod^ Method,
            _Out_opt_ BridgeRT::IAdapterIoRequest^* RequestPtr
            );

        virtual uint32 RegisterSignalListener(
            _In_ BridgeRT::IAdapterSignal^ Signal,
            _In_ BridgeRT::IAdapterSignalListener^ Listener,
            _In_opt_ Platform::Object^ ListenerContext
            );
        virtual uint32 UnregisterSignalListener(
            _In_ BridgeRT::IAdapterSignal^ Signal,
            _In_ BridgeRT::IAdapterSignalListener^ Listener
            );

		//
		// IBACnetNotificationListener implementation
		//
		virtual void OnEvent(_In_ BACNET_EVENT_PARAMETERS^ EventParameters);

        //
        //  Routine Description:
        //      NotifySignalListener is called by the Adapter to notify and registered
        //      signal listener of an intercepted signal.
        //
        //  Arguments:
        //
        //      Signal - The signal object to notify listeners.
        //
        //  Return Value:
        //      ERROR_SUCCESS,
        //      ERROR_INVALID_HANDLE: Invalid signal object.
        //
        uint32 NotifySignalListener(
            _In_ BridgeRT::IAdapterSignal^ Signal
            );

        //
        // Construction
        //
        BACnetAdapter();
        virtual ~BACnetAdapter();

    internal:
        bool IsAllowedDevice(Platform::String^ DeviceModelName);

    protected private:
        uint32 createSignals();

        BridgeRT::IAdapterSignal^ getSignalByName(Platform::String^ SignalName);

        DWORD deviceDiscoveryThreadEntry();

        //
        // IBACnetNotificationListener handlers
        //
        void onNewDeviceEvent(_In_ BACNET_EVENT_PARAMETERS^ EventParameters);
        void onChangeOfValue(_In_ BACNET_EVENT_PARAMETERS^ EventParameters);
        void onSetValueAck(_In_ BACNET_EVENT_PARAMETERS^ EventParameters);

    protected private:

        // Adapter information
        Platform::String^ vendor;
        Platform::String^ adapterName;
        Platform::String^ version;
        // the prefix for AllJoyn service should be something like
        // com.mycompany (only alpha num and dots) and is used by the Device System Bridge
        // as root string for all services and interfaces it exposes
        Platform::String^ exposedAdapterPrefix;

        // name and GUID of the DSB/Adapter application that will be published on AllJoyn
        Platform::String^ exposedApplicationName;
        Platform::Guid exposedApplicationGuid;

        // Devices
        std::vector<BridgeRT::IAdapterDevice^> devices;

        // Signals
        std::vector<BridgeRT::IAdapterSignal^> signals;

        // Sync object
        DsbCommon::CSLock lock;

        //
        // Signal listener entry
        //
        struct SIGNAL_LISTENER_ENTRY
        {
            SIGNAL_LISTENER_ENTRY(
                BridgeRT::IAdapterSignal^ SignalToRegisterTo,
                BridgeRT::IAdapterSignalListener^ ListenerObject,
                Platform::Object^ ListenerContext
                )
                : Signal(SignalToRegisterTo)
                , Listener(ListenerObject)
                , Context(ListenerContext)
            {
            }

            // The  signal object
            BridgeRT::IAdapterSignal^ Signal;

            // The listener object
            BridgeRT::IAdapterSignalListener^ Listener;

            //
            // The listener context that will be
            // passed to the signal handler
            //
            Platform::Object^ Context;
        };

        // A map of signal handle (object's hash code) and related listener entry
        std::multimap<int, SIGNAL_LISTENER_ENTRY> signalListeners;

        // Device object ID -> device lookup
        std::map<ULONG, BridgeRT::IAdapterDevice^> deviceLookup;

        // The device discovery thread
        DsbCommon::MemberThread<BACnetAdapter> deviceDiscoveryThread;

        // The BACnet stack interface
        BACnetInterface^ stackInterface;

        // Adapter configuration
        AdapterConfig adapterConfig;
    };

} // namespace AdapterLib


text:
Light form validation plugin for jQuery.  Goodness only ships with a `required` rule, otherwise you write the validation rules you need.  There is no included feedback markup or error styles.  The plugin validates form fields based on rules you write and set as class names on the input field (or field container) and adds or removes classes based on validation status.  An example `required` rule would test a text field for anything but an empty string.  If validation passes, a `required-good` class would be added to the input field or container for you to use to update styles or markup.  If validation failed, a `required-error` class would be added to the input field or container.  You can apply multiple rules to a single field and more general `good` and `error` classes will be added to the field or container after validating all the rules.

## Usage

### INIT:

Call the `$.fn.goodness()` method on a jQuery selector that returns a form element. ex: `$('#good-form').goodness()`

The init method can be passed all the options you need to customize for your form. Available options and defaults:

```
$('#good-form').goodness({

	// This selector string should return the element that you will add rule classes to. Default to the input elements themselves, not a parent container.
	inputContainerSelector: 'input, textarea, select',

	// This selector string should return the types of elements you want to be considered for validation.
	validationElementSelector: 'input:not([type=submit]):not([type=hidden]):not([type=reset]), textarea, select',

	// Do validation on input element change event
	validateOnChange: false,

	// Emit events
	emitEvents: false,

	// Object containing the validation rules. Keys are the class name you add the the container element to validate against the rule.
	rules: {
		'required': /^(?!\s*$).+/
	}

});
```

The init method returns the Goodness instance. ex: ` var goodForm = $('#good-form').goodness()`

### RULES:

When defining the rules in the `init` method `rules` option, the key should be the class name that you apply to the input container to make it abide by the rule, and the value, or rule itself, can be defined in a few different ways:

#### Regex

Simply using a regex as the value of your rule will test the input elements value against the regex.

```
...
// Create a rule that can only contain numbers.
rules: {
	'only-numbers': /^[0-9]*$/
}
...
```

#### Function

You can define a function that will be run each time the input element is validated.  This function will be passed the value of the input element, a jQuery reference to the input element itself, and a jQuery reference to the entire form element.  This function should return either the number 1 or boolean true if the rule was passed, and the number 0 or boolean false if the rule was failed. ANY other return value will be considered as neither passing or failing and neither of the appropriate class names will be added to the elements container.

```
...
// Create a rule that only passes if the input element has the 'checked' attribute
rules: {
	'must-check': function(value, $element, $form) {
		return $element.is(':checked');
	}
}
...
```
No matter which way you define the rules, class names will be added or removed from your input element or container.  These class names will be prefixed with your rule name, ex: `only-numbers-good` or `must-check-error`.  A more general class will be added if the input element passed all of it's rules or not, `good` or `error`.


text:
title: "Example Anonymous Classes In PHP 7"
layout: post
tag:
- Php
comments: true
author: nurulfajar
---

In PHP 7 Anonymous classes can now be defined using new class. Anonymous class can be used in place of a full class definition.

### Example
```php
<?php
   interface Logger {
      public function log(string $msg);
   }

   class Application {
      private $logger;

      public function getLogger(): Logger {
         return $this->logger;
      }

      public function setLogger(Logger $logger) {
         $this->logger = $logger;
      }
   }

   $app = new Application;
   $app->setLogger(new class implements Logger {
      public function log(string $msg) {
         print($msg);
      }
   });

   $app->getLogger()->log("Selamat Datang");
?>
```
It produces the following browser output:
```
Selamat Datang
```


text:
package com.codeborne.selenide.impl;

import com.codeborne.selenide.Driver;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;

import java.util.List;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

final class CollectionSnapshotTest {

  private final CollectionSource originalCollection = mock(CollectionSource.class);

  @AfterEach
  void verifyNoMoreInteractionsOnOriginalCollection() {
    verify(originalCollection).getElements();
    verifyNoMoreInteractions(originalCollection);
  }

  @Test
  void getOriginalCollectionSnapshotElements() {
    WebElement mockedWebElement1 = mock(WebElement.class);
    WebElement mockedWebElement2 = mock(WebElement.class);

    List<WebElement> originalCollectionElements = asList(mockedWebElement1, mockedWebElement2);
    when(originalCollection.getElements()).thenReturn(originalCollectionElements);

    CollectionSnapshot collectionSnapshot = new CollectionSnapshot(originalCollection);
    List<WebElement> snapshotCollectionElements = collectionSnapshot.getElements();

    assertThat(snapshotCollectionElements).isNotSameAs(originalCollectionElements);
    assertThat(snapshotCollectionElements).isEqualTo(originalCollectionElements);

    // Returns snapshot version nevertheless how many times we call getElements()
    List<WebElement> snapshotCollectionElements2 = collectionSnapshot.getElements();
    assertThat(snapshotCollectionElements2).isSameAs(snapshotCollectionElements);
    assertThat(snapshotCollectionElements2).isEqualTo(snapshotCollectionElements);
  }

  @Test
  void getOriginalCollectionSnapshotElement() {
    WebElement mockedWebElement = mock(WebElement.class);

    when(originalCollection.getElements()).thenReturn(singletonList(mockedWebElement));

    WebElement collectionElement = new CollectionSnapshot(originalCollection).getElement(0);
    assertThat(collectionElement).isEqualTo(mockedWebElement);
  }

  @Test
  void description() {
    WebElement mockedWebElement1 = mock(WebElement.class);
    WebElement mockedWebElement2 = mock(WebElement.class);

    when(originalCollection.description()).thenReturn("Collection description");
    when(originalCollection.getElements()).thenReturn(asList(mockedWebElement1, mockedWebElement2));

    CollectionSnapshot collectionSnapshot = new CollectionSnapshot(originalCollection);
    assertThat(collectionSnapshot.description()).isEqualTo("Collection description.snapshot(2 elements)");
    // Call one more time to check that getElements() is executed only once
    assertThat(collectionSnapshot.description()).isEqualTo("Collection description.snapshot(2 elements)");

    verify(originalCollection, times(2)).description();
  }

  @Test
  void driver() {
    Driver driver = mock(Driver.class);

    when(originalCollection.driver()).thenReturn(driver);

    CollectionSnapshot collectionSnapshot = new CollectionSnapshot(originalCollection);
    assertThat(collectionSnapshot.driver()).isEqualTo(driver);

    verify(originalCollection).driver();
  }
}


text:
class RenameSpreeRefundReturnAuthorizationId < ActiveRecord::Migration
  def change
    rename_column :spree_refunds, :return_authorization_id, :customer_return_id
  end
end


text:
package com.tmoncorp.apipotion.spring.clientinfo;

import com.tmoncorp.apipotion.core.clientinfo.ClientPlatform;

public class LagacyPlatformTransrator {

    private LagacyPlatformTransrator() {
        throw new AssertionError("static utility class");
    }

    private static ClientPlatform fromPrefix(String platform) {

        if (platform.startsWith("M") || platform.startsWith("m")) {
            return ClientPlatform.MOBILE;
        }

        if (platform.startsWith("A") || platform.startsWith("a")) {
            return ClientPlatform.DEVICE;
        }

        if (platform.startsWith("P") || platform.startsWith("p")) {
            return ClientPlatform.NORMAL;
        }
        return ClientPlatform.DEVICE;
    }

    public static ClientPlatform fromMobilePC(String platform) {
        return fromPrefix(platform);
    }

    public static ClientPlatform fromMPCString(String platform) {
        return fromPrefix(platform);
    }

    public static String toMobilePC() {
        ClientPlatform platform = ClientInfoService.getInfo().getPlatform();
        if (platform == ClientPlatform.MOBILE)
            return "MOBILE";
        if (platform == ClientPlatform.DEVICE)
            return "APP";
        if (platform == ClientPlatform.NORMAL)
            return "PC";
        return "MOBILE";
    }

    public static String toMobilePClowerCase() {
        ClientPlatform platform = ClientInfoService.getInfo().getPlatform();
        if (platform == ClientPlatform.MOBILE)
            return "mobile";
        if (platform == ClientPlatform.DEVICE)
            return "app";
        if (platform == ClientPlatform.NORMAL)
            return "pc";
        return "mobile";
    }

}


text:
#include "mitkTestingMacros.h"

#include <vtkMitkThickSlicesFilter.h>

#include "mitkImage.h"
#include "mitkImageWriteAccessor.h"

#include <vtkDataArray.h>
#include <vtkImageData.h>
#include <vtkPointData.h>

class vtkMitkThickSlicesFilterTestHelper
{
public:
  static mitk::Image::Pointer CreateTestImage(int min, int max)
  {
    mitk::PixelType pixelType(mitk::MakeScalarPixelType<unsigned char>());
    mitk::Image::Pointer testImage = mitk::Image::New();
    auto dim = new unsigned int[3];
    dim[0] = 10;
    dim[1] = 10;
    dim[2] = max + 1 - min;
    testImage->Initialize(pixelType, 3, dim);
    size_t buffer_size = dim[0] * dim[1] * sizeof(unsigned char);

    for (int i = min; i <= max; ++i)
    {
      mitk::ImageWriteAccessor writeAccess(testImage, testImage->GetSliceData(i - min));
      memset(writeAccess.GetData(), i, buffer_size);
    }

    return testImage;
  }

  static void EvaluateResult(unsigned char expectedValue, vtkImageData *image, const char *projection)
  {
    MITK_TEST_CONDITION_REQUIRED(
      image->GetDimensions()[0] == 10 && image->GetDimensions()[1] == 10 && image->GetDimensions()[2] == 1,
      "Resulting image has correct size");

    auto *value = static_cast<unsigned char *>(image->GetScalarPointer(0, 0, 0));
    MITK_INFO << "Evaluating projection mode: " << projection;
    MITK_INFO << "expected value: " << static_cast<double>(expectedValue);
    MITK_INFO << "actual value: " << static_cast<double>(value[0]);
    MITK_TEST_CONDITION_REQUIRED(value[0] == expectedValue, "Resulting image has correct pixel-value");
  }
};

/**
*  Test for vtkMitkThickSlicesFilter.
*
*/
int vtkMitkThickSlicesFilterTest(int, char *[])
{
  // always start with this!
  MITK_TEST_BEGIN("vtkMitkThickSlicesFilterTest")

  vtkMitkThickSlicesFilter *thickSliceFilter = vtkMitkThickSlicesFilter::New();

  //////////////////////////////////////////////////////////////////////////
  // Image looks like:
  // 000000000
  // 111111111
  // 222222222
  mitk::Image::Pointer testImage1 = vtkMitkThickSlicesFilterTestHelper::CreateTestImage(0, 2);
  thickSliceFilter->SetInputData(testImage1->GetVtkImageData());

  // MaxIP
  thickSliceFilter->SetThickSliceMode(0);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(2, thickSliceFilter->GetOutput(), "MaxIP");

  // Sum
  thickSliceFilter->SetThickSliceMode(1);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(1, thickSliceFilter->GetOutput(), "Sum");

  // Weighted
  thickSliceFilter->SetThickSliceMode(2);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(1, thickSliceFilter->GetOutput(), "Weighted");

  // MinIP
  thickSliceFilter->SetThickSliceMode(3);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(0, thickSliceFilter->GetOutput(), "MinIP");

  // Mean
  thickSliceFilter->SetThickSliceMode(4);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(1, thickSliceFilter->GetOutput(), "Mean");

  //////////////////////////////////////////////////////////////////////////
  // Image looks like:
  // 333333333
  // 444444444
  // 555555555
  // 666666666
  // 777777777
  // 888888888

  mitk::Image::Pointer testImage2 = vtkMitkThickSlicesFilterTestHelper::CreateTestImage(3, 8);
  thickSliceFilter->SetInputData(testImage2->GetVtkImageData());

  // MaxIP
  thickSliceFilter->SetThickSliceMode(0);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(8, thickSliceFilter->GetOutput(), "MaxIP");

  // Sum
  thickSliceFilter->SetThickSliceMode(1);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(5, thickSliceFilter->GetOutput(), "Sum");

  // Weighted
  thickSliceFilter->SetThickSliceMode(2);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(4, thickSliceFilter->GetOutput(), "Weighted");

  // MinIP
  thickSliceFilter->SetThickSliceMode(3);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(3, thickSliceFilter->GetOutput(), "MinIP");

  // Mean
  thickSliceFilter->SetThickSliceMode(4);
  thickSliceFilter->Modified();
  thickSliceFilter->Update();
  vtkMitkThickSlicesFilterTestHelper::EvaluateResult(6, thickSliceFilter->GetOutput(), "Mean");

  thickSliceFilter->Delete();

  MITK_TEST_END()
}


text:
package org.greg.server;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPInputStream;

public class GregServer {
    private static String get(String[] args, String arg, String def) {
        for (int i = 0; i < args.length - 1; ++i) {
            if (args[i].equals("-" + arg))
                return args[i + 1];
        }
        return def;
    }

    private static int get(String[] args, String arg, int def) {
        return Integer.parseInt(get(args, arg, "" + def));
    }

    private static double get(String[] args, String arg, double def) {
        return Double.parseDouble(get(args, arg, "" + def));
    }

    public static void main(String[] args) {
        Trace.writeLine("GregServer started");

        Configuration conf = new Configuration();
        conf.messagePort = get(args, "port", 5676);
        conf.calibrationPort = get(args, "calibrationPort", 5677);
        conf.desiredConfidenceRangeMs = get(args, "confidenceRangeMs", 1);
        conf.maxCalibrationIters = get(args, "maxCalibrationIters", 100);
        conf.minCalibrationIters = get(args, "minCalibrationIters", 10);
        conf.preCalibrationIters = get(args, "preCalibrationIters", 10);
        conf.maxPendingCalibrated = get(args, "maxPendingCalibrated", 1000000);
        conf.maxPendingUncalibrated = get(args, "maxPendingUncalibrated", 100000);
        conf.timeWindowSec = get(args, "timeWindowSec", 5);

        if(Boolean.parseBoolean(get(args, "verbose", "false"))) {
            Trace.ENABLED = true;
        }

        final GregServer server = new GregServer(conf);

        new Thread() {
            public void run() {
                server.acceptMessages();
            }
        }.start();
        new Thread() {
            public void run() {
                server.acceptCalibration();
            }
        }.start();
        new Thread() {
            public void run() {
                server.flushCalibratedMessages();
            }
        }.start();

        new Thread() {
            public void run() {
                try {
                    Thread.currentThread().setPriority(7); // Above normal

                    OutputStream os = new BufferedOutputStream(new FileOutputStream(FileDescriptor.out), 16384);

                    byte[] newline = System.getProperty("line.separator").getBytes("utf-8");

                    while (true) {
                        List<Record> records = server.outputQueue.dequeue();
                        if (records.isEmpty()) {
                            Thread.sleep(50);
                            continue;
                        }

                        for (Record rec : records) {
                            os.write(rec.machine.array, rec.machine.offset, rec.machine.len);
                            os.write(' ');
                            os.write(rec.clientId.array, rec.clientId.offset, rec.clientId.len);
                            os.write(' ');
                            byte[] ts = rec.timestamp.toBytes();
                            os.write(ts);
                            os.write(' ');
                            os.write(rec.message.array, rec.message.offset, rec.message.len);
                            os.write(newline);
                        }
                        os.flush();
                    }
                } catch (Exception e) {
                    Trace.writeLine("Failure while writing records", e);
                }
            }
        }.start();
    }

    private final Configuration conf;
    private final TimeBufferedQueue<Record> outputQueue;

    private final ConcurrentMap<UUID, Queue<Record>> clientRecords = new ConcurrentHashMap<UUID, Queue<Record>>();
    private final ConcurrentMap<UUID, TimeSpan> clientLateness = new ConcurrentHashMap<UUID, TimeSpan>();
    private final AtomicInteger numPendingUncalibratedEntries = new AtomicInteger(0);

    public GregServer(Configuration conf) {
        this.conf = conf;

        Comparator<Record> RECORD_COMPARATOR = new Comparator<Record>() {
            public int compare(Record x, Record y) {
                return x.timestamp.compareTo(y.timestamp);
            }
        };

        this.outputQueue = new TimeBufferedQueue<Record>(
                new TimeSpan(conf.timeWindowSec * 1000000000L),
                PreciseClock.INSTANCE,
                conf.maxPendingCalibrated,
                RECORD_COMPARATOR);
    }

    private void acceptMessages() {
        ServerSocket server = null;
        try {
            server = new ServerSocket(conf.messagePort);
        } catch (IOException e) {
            Trace.writeLine("Cannot create messages acceptor", e);
        }

        int maxConcurrentClients = 16;
        final Semaphore sem = new Semaphore(maxConcurrentClients);

        Executor pool = Executors.newFixedThreadPool(16);

        while (true) {
            try {
                sem.acquire();
            } catch (InterruptedException e) {
                continue;
            }

            final Socket client;
            final InputStream stream;
            try {
                client = server.accept();
                stream = client.getInputStream();
            } catch (Exception e) {
                Trace.writeLine("Failed to accept client or get its input stream", e);
                continue;
            }

            pool.execute(new Runnable() {
                public void run() {
                    try {
                        processRecordsBatch(stream, client.getRemoteSocketAddress());
                    } finally {
                        sem.release();
                        try {
                            client.close();
                        } catch (Exception e) {
                            // Ignore
                        }
                    }
                }
            });
        }
    }

    private void processRecordsBatch(InputStream rawStream, final SocketAddress ep) {
        try {
            InputStream stream = new BufferedInputStream(rawStream, 65536);

            DataInput r = new LittleEndianDataInputStream(stream);
            final UUID uuid = new UUID(r.readLong(), r.readLong());
            boolean useCompression = r.readBoolean();

            clientRecords.putIfAbsent(uuid, new ConcurrentLinkedQueue<Record>());
            final Queue<Record> q = clientRecords.get(uuid);

            final boolean[] skipping = new boolean[] {false};
            final int[] numRead = {0};
            final int[] numSkipped = {0};

            final List<Record> uncalibrated = new ArrayList<Record>();
            final List<Pair<PreciseDateTime, Record>> calibrated = new ArrayList<Pair<PreciseDateTime, Record>>();

            final TimeSpan lateness = clientLateness.get(uuid);

            Sink<Record> sink = new Sink<Record>() {
                public void consume(Record rec) {
                    numRead[0]++;

                    if(lateness == null) {
                        int numPending = numPendingUncalibratedEntries.incrementAndGet();
                        if (numPending < conf.maxPendingUncalibrated) {
                            uncalibrated.add(rec);

                            if (skipping[0]) {
                                Trace.writeLine("Receiving entries from client " + ep + " again, after having skipped " + numSkipped[0]);
                            }
                            skipping[0] = false;
                            numSkipped[0] = 0;
                        } else {
                            numPendingUncalibratedEntries.decrementAndGet();

                            numSkipped[0]++;
                            if (!skipping[0] || numSkipped[0] % 10000 == 0) {
                                Trace.writeLine(
                                        "Uncalibrated records buffer full - skipping entry from client " + ep +
                                                " because there are already " + numPending + " uncalibrated entries. " +
                                                (numSkipped[0] == 1 ? "" : (numSkipped[0] + " skipped in a row...")));
                            }
                            skipping[0] = true;
                        }
                    } else {
                        calibrated.add(absolutizeTime(rec, lateness));
                    }
                }
            };

            readRecords(useCompression ? new GZIPInputStream(stream) : stream, sink);

            // Only publish records to main queue if we read all them successfully (had no exception to this point)
            // Otherwise we'd have duplicates if clients resubmit their records after failure.
            q.addAll(uncalibrated);
            outputQueue.enqueue(calibrated);

            if (skipping[0]) {
                Trace.writeLine("Skipped " + numSkipped[0] + " entries from " + ep + " in a row.");
            }
            Trace.writeLine("Read " + numRead[0] + " entries");
        } catch (Exception e) {// Socket or IO or whatever
            Trace.writeLine("Failed to receive records batch, ignoring", e);
            // Ignore
        }
    }

    private interface Sink<T> {
        void consume(T t);
    }

    private static void readRecords(InputStream stream, Sink<Record> sink) throws IOException {
        DataInput r = new LittleEndianDataInputStream(new BufferedInputStream(stream, 65536));

        int cidLenBytes = r.readInt();
        byte[] cidBytes = new byte[cidLenBytes];
        r.readFully(cidBytes);

        ByteSlice clientId = new ByteSlice(cidBytes, 0, cidBytes.length);

        while (0 != r.readInt()) {
            PreciseDateTime timestamp = new PreciseDateTime(r.readLong());
            int machineLenBytes = r.readInt();
            byte[] machineBytes = new byte[machineLenBytes];
            r.readFully(machineBytes);
            int msgLenBytes = r.readInt();
            byte[] msgBytes = new byte[msgLenBytes];
            r.readFully(msgBytes);

            Record rec = new Record();
            rec.machine = new ByteSlice(machineBytes, 0, machineLenBytes);
            rec.timestamp = timestamp;
            rec.message = new ByteSlice(msgBytes, 0, msgBytes.length);
            rec.serverTimestamp = PreciseClock.INSTANCE.now();
            rec.clientId = clientId;
            sink.consume(rec);
        }
    }

    private void acceptCalibration() {
        ServerSocket calibrationServer = null;
        try {
            calibrationServer = new ServerSocket(conf.calibrationPort);
        } catch (IOException e) {
            Trace.writeLine("Failed to create calibration listener", e);
        }

        Executor executor = Executors.newFixedThreadPool(16);

        while (true) {
            final Socket client;
            try {
                client = calibrationServer.accept();
                client.setTcpNoDelay(true);
            } catch (Exception e) {
                Trace.writeLine("Failed to accept client for calibration", e);
                continue;
            }
            final SocketAddress ep = client.getRemoteSocketAddress();

            executor.execute(new Runnable() {
                public void run() {
                    try {
                        processCalibrationExchange(client, ep);
                    } catch (Exception e) {
                        Trace.writeLine("Failed to process calibration exchange with " + ep, e);
                    } finally {
                        try {
                            client.close();
                        } catch (IOException e) {
                            // Ignore
                        }
                    }
                }
            });
        }
    }

    private void processCalibrationExchange(Socket client, SocketAddress ep) throws IOException {
        InputStream in = client.getInputStream();
        OutputStream out = client.getOutputStream();

        DataOutput w = new LittleEndianDataOutputStream(out);
        DataInput r = new LittleEndianDataInputStream(in);

        UUID uuid = new UUID(r.readLong(), r.readLong());

        // We exchange *ticks* (0.1us intervals)

        // Do some iterations to warm up the TCP connection
        for (int i = 0; i < conf.preCalibrationIters; ++i) {
            w.writeLong(PreciseClock.INSTANCE.now().toUtcNanos());
            r.readLong();
        }

        // The smaller the network roundtrip, the smaller the range of possible
        // asymmetries of network latencies, the more precisely we compute the
        // clock difference.
        long minLatencyNanos = Long.MAX_VALUE;
        long latenessAtMinLatencyNanos = 0;

        for (int i = 0; i < conf.maxCalibrationIters; ++i) {
            PreciseDateTime beforeSend = PreciseClock.INSTANCE.now();
            w.writeLong(beforeSend.toUtcNanos());
            PreciseDateTime clientTime = new PreciseDateTime(r.readLong());
            PreciseDateTime afterReceive = PreciseClock.INSTANCE.now();

            long latencyNanos = (afterReceive.toUtcNanos() - beforeSend.toUtcNanos()) / 2;
            if(latencyNanos < minLatencyNanos) {
                minLatencyNanos = latencyNanos;
                latenessAtMinLatencyNanos = clientTime.toUtcNanos() - beforeSend.toUtcNanos() - latencyNanos;
            }

            if (i >= conf.minCalibrationIters && latencyNanos < conf.desiredConfidenceRangeMs * 1000000L) {
                break;
            }
        }

        TimeSpan lateness = new TimeSpan(latenessAtMinLatencyNanos);
        Trace.writeLine("Clock lateness with client " + ep + " (" + uuid + ") is " + lateness);
        clientLateness.put(uuid, lateness);
    }

    private void flushCalibratedMessages() {
        Thread.currentThread().setPriority(7); // above normal
        while(true) {
            List<Pair<PreciseDateTime, Record>> snapshot = new ArrayList<Pair<PreciseDateTime, Record>>(10000);
            for (Map.Entry<UUID, TimeSpan> p : clientLateness.entrySet()) {
                UUID client = p.getKey();
                TimeSpan lateness = p.getValue();

                Queue<Record> q = clientRecords.get(client);
                if(q != null) {
                    snapshot.clear();
                    for(int i = 0; i < 10000; ++i) {
                        Record r = q.poll();
                        if(r == null) {
                            break;
                        }
                        snapshot.add(absolutizeTime(r, lateness));
                    }
                    Trace.writeLine("Dequeued snapshot: " + snapshot.size());
                    numPendingUncalibratedEntries.addAndGet(-snapshot.size());
                    outputQueue.enqueue(snapshot);
                }
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                continue;
            }
        }
    }

    private static Pair<PreciseDateTime, Record> absolutizeTime(Record rec, TimeSpan lateness) {
        PreciseDateTime t = new PreciseDateTime(rec.timestamp.toUtcNanos() - lateness.toNanos());

        rec.timestamp = t;

        return new Pair<PreciseDateTime, Record>(t, rec);
    }
}


text:
<?php

require_once "Google/Exception.php";

class Google_0814_Auth_Exception extends Google_0814_Exception
{
}


text:
package de.juergens.time

import java.time._
import java.time.temporal.ChronoField._
import java.time.temporal._

import de.juergens.util._

import scala.language.implicitConversions

case class DayOfWeekAdjuster(ordinal: Ordinal, dayOfWeek: DayOfWeek, direction: Direction)
  extends TemporalAdjuster
  with LocalDateAdjuster {

  val adjuster: TemporalAdjuster = TemporalAdjusters.next(dayOfWeek)
  private val Ordinal(number) = ordinal

  override def adjustInto(temporal: Temporal): Temporal = {
    //    require(temporal.isSupported(ChronoField.DAY_OF_WEEK), s"$temporal has to support day-of-week")
    //    temporal.ensuring( _.isSupported(ChronoField.DAY_OF_WEEK))

    import TemporalAdjusters.{next, previous}

    val adjuster: TemporalAdjuster = direction match {
      case Up => next(dayOfWeek)
      case Down => previous(dayOfWeek)
    }

    var date : Temporal =
      if (temporal.isSupported(EPOCH_DAY)) {
        LocalDate.from(temporal)
      } else {
        YearMonth.from(temporal).atDay(1)
      }

    if (number > 0) {
      date = adjuster.adjustInto(date)
    }
    if (date == temporal && number > 0) {
      date = adjuster.adjustInto(date)
    }
    if (number > 1) {
      date = (1 to (number - 1)).foldLeft[Temporal](date) { (x: Temporal, _) => adjuster.adjustInto(x) }
    }

//    assert(temporal.isInstanceOf[LocalDate])

    val time: LocalTime = temporal.query(TemporalQueries.localTime)
    if (time != null)
      date.`with`(time)
    else date
  }
}


text:
import { feathers, Id, Params } from '@feathersjs/feathers'
import socketio from '@feathersjs/socketio'
import '@feathersjs/transport-commons'
import { MemoryService } from '@feathersjs/memory'

// eslint-disable-next-line no-extend-native
Object.defineProperty(Error.prototype, 'toJSON', {
  value() {
    const alt: any = {}

    Object.getOwnPropertyNames(this).forEach((key: string) => {
      alt[key] = this[key]
    }, this)

    return alt
  },
  configurable: true,
  writable: true
})

// Create an in-memory CRUD service for our Todos
class TodoService extends MemoryService {
  async get(id: Id, params: Params) {
    if (params.query.error) {
      throw new Error('Something went wrong')
    }

    const data = await super.get(id)

    return Object.assign({ query: params.query }, data)
  }

  async customMethod(data: any, { provider }: Params) {
    return {
      data,
      provider,
      type: 'customMethod'
    }
  }
}

export function createServer() {
  const app = feathers()
    .configure(socketio())
    .use('/', new TodoService())
    .use('/todos', new TodoService(), {
      methods: ['find', 'get', 'create', 'update', 'patch', 'remove', 'customMethod']
    })
  const service = app.service('todos')
  const rootService = app.service('/')
  const publisher = () => app.channel('general')
  const data = {
    text: 'some todo',
    complete: false
  }

  app.on('connection', (connection) => app.channel('general').join(connection))

  rootService.create(data)
  rootService.publish(publisher)

  service.create(data)
  service.publish(publisher)

  return app
}


text:
var chai = require('chai');
var chaifs = require('chai-fs');
var glob = require('glob');
var AddonTestApp = require('ember-cli-addon-tests').AddonTestApp;

var expect = chai.expect;
chai.use(chaifs);

describe.skip('acceptance: import tachyons css', function () {
	this.timeout(300000);

	var app;

	before(function () {
		app = new AddonTestApp();
		return app.create('sandbox');
	});

	it('imports tachyons.css by default', function () {
		return app.runEmberCommand('build')
			.then(function () {
				var borderBoxClass = new RegExp('.border-box { box-sizing: border-box; }', 'i'),
					dbClass = new RegExp('.db { display: block; }', 'i'),
					ptOClass = new RegExp('.pt0 { padding-top: 0; }'),
					vendorCSSPath = app.filePath('dist/assets/vendor.css');

				expect(vendorCSSPath).to.be.a.file();
				expect(vendorCSSPath).to.be.a.file().and.not.empty;
				expect(vendorCSSPath).to.have.content.that.match(borderBoxClass);
				expect(vendorCSSPath).to.have.content.that.match(dbClass);
				expect(vendorCSSPath).to.have.content.that.match(ptOClass);
			})
	});

	it('imports tachyons.min.css for production builds with --environment=production', function () {
		var legendClass = new RegExp('legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}', 'i'),
			vendorCSSPath = 'dist/assets/vendor-*.css';

		return app.runEmberCommand('build', '--environment=production')
			.then(function () {
				expect(fingerprintedAssetAt(vendorCSSPath)).to.be.a.file();
				expect(fingerprintedAssetAt(vendorCSSPath)).to.be.a.file().and.not.empty;
			})
	});

	function fingerprintedAssetAt(path) {
		var globPath = app.filePath(path);
		var files = glob.sync(globPath);

		expect(files.length).to.equal(1, globPath);

		return files[0];
	}
});


text:
TransactionManager
------------------

The `TransactionManager` is in charge of submitting transactions to the network
in such a way that is resilient to poor network conditions (busy, dropouts).

There is, in fact, a non 100% success rate for every transaction submission.
This can be due to conditions at the transport layer, or the node submitted to
could be busy, completely dropping a submission, or even outright rejecting it,
due to an insufficient fee for the current load.

Therefore, client libraries will present an API that in the background
automatically handles resubmitting transactions (where it makes sense to do so)

There are 3 phases to submitting a transaction and verifying it has succeeded:

  1. Submission to a ripple node

    This is done by making a `submit` RPC request.

    The transaction has entered the transport layer, and could be resubmitted  by
    3rd parties (helpfully or maliciously)

  2. Transaction provisionally successful

    At this point the transaction has succeeded in being applied to the local
    node's ledger. It is then distributed amongst the network. It may take more
    than one ledger close before it's finalized.

    The rippled node will respond to the (stage 1) `submit` request.

  3. Transaction validated

    The transaction has made it into a validated ledger.

    The local node will send out to subscribers of a given account, notification
    of any transactions that affect it as they are validated by the network.

Locally, from the client perspective it's only possible to really know that the
first step has failed.

It's possible (and has been observed), that at times there will be no response
or notifications from the node the client is connected to, for a transaction
that will ultimately find its way into a validated ledger.

It's very important to realize that `no response` isn't necessarily an indication
of failure.

Each `Transaction` submitted to the network, in binary form, has the following:

  - A transaction signature `TxnSignature` field
    - what is signed is a hash of the transaction contents in binary form
    - this is ecdsa, which has a random component
      - signing the EXACT same content multiple times will result in multiple
        unique signatures.

  - a `hash` (sometimes referred to as a transactionID)
    - dubbed a `hash`, due to it being a hash of the binary representation
      of the transactions.

      - IMPORTANT: the contents include the RANDOM TxnSignature

      - The hash is used to map transaction notification messages
        to submitted transactions in the pending queue.

  - `Fee`

    - This is the amount of drops (1e-6 XRP) destroyed.

    - There is a minimum Fee, which scales with the current load on the node
      submitted to.

So:
  - May not get response/notification of successful submission/validation
  - May need to change the `Fee` and resubmit for a transaction to be applied
  - Transactions are identified by hash of binary repr (incl. Fee and random sig)

Therefore, as a transaction gets submitted multiple times, if the transaction
binary representation content changes, eg. due to a Fee change, it becomes
necessary to look out for ALL submitted transactionIDs to map incoming transaction
notifications to a given Transaction.

To understand why, the `Sequence` field must also be considered:

  - Sequence

    In a new Account, there is an integer field `Sequence`, which is initialized
    with the value `1`.

    Each transaction submitted by the account, must declare a `Sequence` too.
    The transaction sequence must exactly match that stored in the account node.

    Any transaction that is successful increments the Sequence in the account
    node.

    This is to stop replay attacks. Each transaction can be applied only once.

It's possible when multiple clients are submitting transactions for the same
account that there will be contention for Sequence numbers. One client will need
to increment the sequence on a transaction before resubmission for it to succeed.

How can this be detected? As transaction notifications come in, the hash of each
transaction is compared against that of all the pending transactions. If a hash
matches, the transaction is cleared, otherwise if the Sequence matches any of
the pending transactions, it's assumed that the Sequence has been consumed by
another client.

  >>> the hash of each transaction is compared against that of all the pending
  >>> transactions

Actually. it must be compared against **all hashes of any transaction serializations
that entered the transport layer**, not just the most recent one submitted, otherwise
there runs the risk of submitting the same transaction more than once. (The
Sequence will be incremented, as it's assumed that a transaction submitted by
another client consumed the Sequence, when actually it's just a prior submission)

Robust transaction validation
-----------------------------

For various reasons the validated transaction subscription messages could
be missed.

  - Transport layer issues
    - messages missed

  - Simply stalled nodes

Therefore, periodically, when there are pending transactions, the transaction
manger will request a list of transactions from the server, from ledger $n
and forward. $n is determined by looking at the ledger_index of the oldest
submission in the pending queue of transactions.

The same logic that handles clearing transactions from the account subscription
transaction stream is applied to each transaction in the transaction list.

The rpc command `account_tx` is used to get the list of transactions.

Robust transaction invalidation
-------------------------------

You keep submitting until you get a final result, either a response to submit
with a `final` disposition, or a validated transaction (via some combination
of subscription/account_tx).

It must always be kept in mind that once a transaction goes on the wire it can
be played back at any time[1], helpfully or maliciously.

This means, that for failed transactions, the transaction `Sequence` must be
consumed (via a `noop` transaction or Fee claimed tec*), or that an expiry be
placed on the transaction.

In ripple, expiry is done by declaring `LastLedgerSequence` which specifies
the last valid `ledger_index` that a transaction is valid for. In this way,
even if a Sequence is not consumed, the vulnerability to replay is greatly
reduced.

[1] Without declaring `LastLedgerSequence` there is no expiry on transactions.


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Topics</title>

    <link href="css/bootstrap.min.css" rel="stylesheet">

    <link href="css/main.css" rel="stylesheet">

          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
            Toggle navigation

          </button>
          Brand

Index

Topic

Hightlight

Message

          <form class="navbar-form navbar-left" role="search">

                    <input type="text" class="form-control typeahead" placeholder="Search for Answers.." autocomplete="off">

          </form>

 My Home Page

 My Message

 Setting

 Logout

            Topics
            7 topics subscribed

            Topic1
            Topic2
            Topic3
            Topic3
            Topic3
            pic3
            Topic3
            Topic3
            Topic3
            Topic3
            Topic3
            Topic3Topics
            Topic3
            pic3
            Topic3
            Topic3
            Topic3
            ic3
            Topic3
            Topic3
            Topic3
            Topic3
            Topic3
            Topic3
            Topic3

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

Topic Name

                Subscribe

Cras sit amet nibh libero, in gravida nulla. Cras sit amet nibh libero, in gravida nulla.

              <button type="button" class="btn btn-default">More</button>

Popular Topics

Media heading

              999 Subscriptions

            Looking to Start Your CS Career in the Bay Area?

Media heading

              999 Subscriptions

            Looking to Start Your CS Career in the Bay Area?

Media heading

              999 Subscriptions

            如何评价《权力的游戏》第六季第九集S06E09 「Battle of the Bastards」?

            © 2016 Ding & KKP All Rights Reserved


text: export * from './module/module';


text:
var precss = require('precss')
var cssimport = require('postcss-import')
var cssnext = require('postcss-cssnext')
var ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  entry: './index.js',
  template: './index.html',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /\.css$/,
      loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
    }]
  },
  postcss: function (webpack) {
    return [
      precss,
      cssimport({
        addDependencyTo: webpack
      }),
      cssnext()
    ]
  },
  plugins: [
    new ExtractTextPlugin('bundle.css')
  ]
}


text:
def bottleSong():
    bottles = 99

    while bottles > 0:
        if bottles == 1:
            print(str(bottles) + " bottles of beer on the wall, " + str(bottles) + " bottle of beer.", end=" ")
        else:
            print(str(bottles) + " bottles of beer on the wall, " + str(bottles) + " bottles of beer.", end=" ")
        bottles -= 1
        if bottles == 1:
            print("Take one down and pass it around, " + str(bottles) + " bottle of beer on the wall.", end=" ")
        elif bottles == 0:
            print("Take one down and pass it around, no more bottles of beer on the wall.", end=" ")
        else:
            print("Take one down and pass it around, " + str(bottles) + " bottles of beer on the wall.", end=" ")
    print("No more bottles of beer on the wall, no more bottles of beer.", end=" ")
    print("Go to the store and buy some more, 99 bottles of beer on the wall.", end=" ")

if __name__ == "__main__":
    bottleSong()


text:
package de.tdlabs.keycloak.ext.events.forwarder;

import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableSet;

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

import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.EventListenerProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;

public class JmsEventListenerProviderFactory implements EventListenerProviderFactory {

	private static final Logger LOG = Logger.getLogger(JmsEventListenerProviderFactory.class);

	/**
	 * This ID must not be changed since the extension is registered with that
	 * name in Keycloak.
	 */
	static final String ID = "idm-keycloak-event-listener-jms";

	private static final Set<String> DEFAULT_INCLUDED_CONTEXT_ACTIONS = new HashSet<>(asList( //
			"REGISTER", //
			"REVOKE_ROLE", //
			"GRANT_ROLE", //
			"UPDATE_EMAIL", //
			"UPDATE_PROFILE", //
			"UPDATE_PASSWORD", //
			"UPDATE_TOTP", //
			"REMOVE_TOTP", //
			"DELETE_USER", //
			"CREATE_USER", //
			"RESET_PASSWORD", //
			"MANAGE_USER", //
			"VERIFY_EMAIL" //
	));

	private Set<String> includedContextActions;

	@Override
	public EventListenerProvider create(KeycloakSession keycloakSession) {

		ForwardingEventListenerProvider provider = new ForwardingEventListenerProvider(keycloakSession,
				unmodifiableSet(includedContextActions));
		keycloakSession.enlistForClose(provider);

		return provider;
	}

	@Override
	public void init(Config.Scope config) {

		LOG.infov("Creating IdM Keycloak extension component={0}", Utils.toComponentIdString(this));
		this.includedContextActions = new HashSet<>(DEFAULT_INCLUDED_CONTEXT_ACTIONS);
	}

	@Override
	public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
		// noop
	}

	@Override
	public void close() {

		LOG.infov("Closing IdM Keycloak extension component={0}", Utils.toComponentIdString(this));
		// NOOP
	}

	@Override
	public String getId() {
		return ID;
	}
}


text:
layout: post
title: "When this goes off the rails, it goes way off the rails"
share-img: "https://www.asianturfgrass.com/img/utk_poa_2018.jpg"
tags: [weeds, podcast, science, research]
---

I really enjoyed listening to Frank Rossi and Jim Brosnan discuss weed control, *Poa annua*, herbicide resistance, and glyphosate in their [recent discussion on TurfNet's Frankly Speaking](https://www.turfnet.com/podcasts/rossi/brosnan/).

<iframe width="100%" height="180px" src="//percolate.blogtalkradio.com/offsiteplayer?hostId=705817&episodeId=11550103" frameborder="0" allowfullscreen></iframe>

I'd recommend listening to this to learn more about some important turfgrass management challenges and the research being done right now to find solutions.

The section about herbicide resistance was especially interesting. After Brosnan described a survey of *Poa annua* in Tennessee, Rossi asked if he understood correctly that "almost 90% of the [*Poa annua* control] programs are breaking down in one way, shape, or form?"

Brosnan confirmed that was correct, and explained that "when this goes off the rails, it goes **way** off the rails ... we want you to be diversifying what you're doing so you're not selecting for resistance on your golf course, but the answer to a resistance problem is not gonna come from a jug."


text:
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace GitLab.VisualStudio.Shared
{
    public static class PropertyNotifierExtensions
    {
        public static void RaisePropertyChange<TSender>(this TSender This, [CallerMemberName] string propertyName = null)
           where TSender : INotifyPropertySource
        {
            This.RaisePropertyChanged(propertyName);
        }
    }

    public interface INotifyPropertySource
    {
        void RaisePropertyChanged(string propertyName);
    }

    public abstract class NotificationAwareObject : INotifyPropertyChanged, INotifyPropertySource
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}