{"action":"created","comment":{"url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/comments/217384681","pull_request_review_id":155041260,"id":217384681,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxNzM4NDY4MQ==","diff_hunk":"@@ -0,0 +1,343 @@\n+package org.bonej.ops.ellipsoid;\n+\n+import net.imagej.ops.Op;\n+import net.imagej.ops.special.function.AbstractBinaryFunctionOp;\n+import net.imglib2.util.ValuePair;\n+import org.joml.*;\n+import org.scijava.plugin.Parameter;\n+import org.scijava.plugin.Plugin;\n+\n+import java.util.*;\n+import java.util.stream.Collectors;\n+\n+\n+/**\n+ * Tries to do one step of an {@link Ellipsoid} decomposition, starting from a point and a list of possible other points to collide with\n+ * <p>\n+ * The ellipsoid decomposition is drawn from the paper of Bischoff and Kobbelt, 2002 (https://www.graphics.rwth-aachen.de/media/papers/ellipsoids1.pdf)\n+ * The variable naming widely follows Bischoff and Kobbelt's nomenclature, it is recommended to read this code in conjunction with the paper.\n+ * The Ellipsoid-Plane intersection is done slightly differently, using the {@link EllipsoidPlaneIntersection}. This op starts growing an ellipsoid\n+ * from the starting point p, and keeps growing in various directions until it hits three more points (q,r,s). If less than four distinct points are found,\n+ * the op returns an empty ellipsoid. More details on the growing process are in the original publication.\n+ * </p>\n+ *\n+ * @author Alessandro Felder\n+ */\n+@Plugin(type = Op.class)\n+public class FindEllipsoidFromBoundaryPoints extends AbstractBinaryFunctionOp<List<ValuePair<Vector3d,Vector3d>>,Vector3d,Optional<Ellipsoid>> {\n+\n+    private static QuadricToEllipsoid quadricToEllipsoid = new QuadricToEllipsoid();\n+    private static EllipsoidPlaneIntersection intersectionOp = new EllipsoidPlaneIntersection();\n+\n+    @Parameter(persist=false, required = false)\n+    private double calibratedLargestImageDimension = 100.0;\n+\n+    @Override\n+    public Optional<Ellipsoid>calculate(List<ValuePair<Vector3d,Vector3d>> fourVerticesWithNormals, Vector3d centre) {\n+        List<Vector3d> fourVertices = new ArrayList<>();\n+        fourVerticesWithNormals.forEach(v -> fourVertices.add(v.getA()));\n+\n+        fourVerticesWithNormals.sort(Comparator.comparingDouble(p->euclideanDistance(p.getA(),centre)));\n+        VertexWithNormal p = new VertexWithNormal(fourVerticesWithNormals.get(0));\n+        fourVertices.remove(p.getVertex());\n+\n+        ValuePair<VertexWithNormal, Double> qAndRadius = calculateQ(fourVertices, p);\n+        if (qAndRadius == null || qAndRadius.getB()>calibratedLargestImageDimension) return Optional.empty();\n+        fourVertices.remove(qAndRadius.getA().getVertex());\n+\n+        Vector3d np = new Vector3d(p.getNormal());\n+        np.mul(qAndRadius.getB());\n+        p.setNormal(np);\n+\n+        Vector3d c = new Vector3d(p.getNormal());\n+        c.add(p.getVertex());\n+        Matrix4d q1 = getQ1(c, qAndRadius.getB());\n+        Matrix4d q2 = getQ2(p, qAndRadius.getA());\n+\n+        ValuePair<Vector3d, Double> rAndAlpha = calculateSurfacePointAndGreekCoefficient(q1, q2, fourVertices);\n+        if (rAndAlpha == null) return Optional.empty();\n+        fourVertices.remove(rAndAlpha.getA());\n+\n+        Matrix4d q1PlusAlphaQ2 = new Matrix4d(q2);\n+        Matrix4d fullScalingMatrix = new Matrix4d();\n+        fullScalingMatrix.scaling(rAndAlpha.getB());\n+        fullScalingMatrix.m33(rAndAlpha.getB());\n+        q1PlusAlphaQ2.mul(fullScalingMatrix, q1PlusAlphaQ2);\n+        q1PlusAlphaQ2.add(q1, q1PlusAlphaQ2);\n+\n+        Optional<Ellipsoid> ellipsoid = quadricToEllipsoid.calculate(q1PlusAlphaQ2);\n+        if(!ellipsoid.isPresent()) return ellipsoid;\n+\n+        Matrix4d q3 = getQ3(Arrays.asList(p.getVertex(), qAndRadius.getA().getVertex(), rAndAlpha.getA()), ellipsoid.get());\n+\n+        ValuePair<Vector3d, Double> sAndBeta = calculateSurfacePointAndGreekCoefficient(q1PlusAlphaQ2, q3, fourVertices);\n+        if (sAndBeta == null) return ellipsoid;\n+\n+        Matrix4d q1PlusAlphaQ2plusBetaQ3 = new Matrix4d(q3);\n+        fullScalingMatrix.scaling(sAndBeta.getB());\n+        fullScalingMatrix.m33(sAndBeta.getB());\n+        q1PlusAlphaQ2plusBetaQ3.mul(fullScalingMatrix, q1PlusAlphaQ2plusBetaQ3);\n+        q1PlusAlphaQ2plusBetaQ3.add(q1PlusAlphaQ2);\n+\n+        return quadricToEllipsoid.calculate(q1PlusAlphaQ2plusBetaQ3);\n+    }\n+\n+    /**\n+     * calculates the quadric denoted by Q_1 in the original paper\n+     *\n+     * @param sphereCentre centre of the sphere touching p and q\n+     * @param radius       radius of the sphere touching p and q\n+     * @return Q_1\n+     */\n+    static Matrix4d getQ1(Vector3d sphereCentre, double radius) {\n+        Matrix3d identity = new Matrix3d();\n+        identity = identity.identity();\n+        Vector4d minusSphereCentre = new Vector4d(-sphereCentre.x(), -sphereCentre.y(), -sphereCentre.z(),0);\n+        Matrix4d q1 = new Matrix4d(identity);\n+        q1.setColumn(3, new Vector4d(minusSphereCentre));\n+        q1.setRow(3, new Vector4d(minusSphereCentre));\n+        q1.m33(sphereCentre.lengthSquared() - radius * radius);\n+        return q1;\n+    }\n+\n+    /**\n+     * Calculates the quadric denoted by Q_2 in the original paper\n+     *\n+     * @param pnp p and normal at p\n+     * @param qnq q and normal at q\n+     * @return the 4x4 matrix Q_2\n+     */\n+    static Matrix4d getQ2(final VertexWithNormal pnp, final VertexWithNormal qnq) {\n+        Vector3d p = pnp.getVertex();\n+        Vector3d np = pnp.getNormal();\n+        Vector3d q = qnq.getVertex();\n+        Vector3d nq = qnq.getNormal();\n+\n+        Matrix3d NRotation = new Matrix3d();\n+\n+        NRotation.m00 = -np.x() * nq.x();\n+        NRotation.m01 = -np.x() * nq.y();\n+        NRotation.m02 = -np.x() * nq.z();\n+\n+        NRotation.m10 = -np.y() * nq.x();\n+        NRotation.m11 = -np.y() * nq.y();\n+        NRotation.m12 = -np.y() * nq.z();\n+\n+        NRotation.m20 = -np.z() * nq.x();\n+        NRotation.m21 = -np.z() * nq.y();\n+        NRotation.m22 = -np.z() * nq.z();\n+\n+        Matrix3d NRotationTransposed = new Matrix3d(NRotation);\n+        NRotationTransposed.transpose();\n+        Matrix3d q2Rotation = new Matrix3d(NRotation);\n+        q2Rotation.add(NRotationTransposed);\n+        q2Rotation.scale(0.5);\n+\n+        double nqDotqHalf = nq.dot(q) / 2.0;\n+        double npDotpHalf = np.dot(p) / 2.0;\n+\n+        Vector3d q2Translation = new Vector3d(np.x() * nqDotqHalf + nq.x() * npDotpHalf, np.y() * nqDotqHalf + nq.y() * npDotpHalf, np.z() * nqDotqHalf + nq.z() * npDotpHalf);\n+\n+        Matrix4d quadric2 = new Matrix4d(q2Rotation);\n+        quadric2.setColumn(3, new Vector4d(q2Translation,1));\n+        quadric2.setRow(3, new Vector4d(q2Translation,1));\n+        quadric2.m33(-np.dot(p) * nq.dot(q));\n+        return quadric2;\n+    }\n+\n+\n+    /**\n+     * Calculates the elliptic cylinder denoted by Q_3 in the original paper\n+     *\n+     * @param pqr       three non-collinear points defining a plane\n+     * @param ellipsoid ellipsoid through p,q, and r\n+     * @return a 4x4 matrix representation of the elliptic cylinder defined by the intersection ellipse of pqr and qBar\n+     */\n+    private static Matrix4d getQ3(final List<Vector3d> pqr, Ellipsoid ellipsoid) {\n+        final Vector3d p = new Vector3d(pqr.get(0));\n+        final Vector3d q = new Vector3d(pqr.get(1));\n+        final Vector3d r = new Vector3d(pqr.get(2));\n+\n+        Vector3d interiorPoint = new Vector3d(p);\n+        interiorPoint.mul(-1);\n+        interiorPoint.add(q);\n+        interiorPoint.mul(0.5);\n+        interiorPoint.add(p);\n+\n+        Vector3d planeNormal = new Vector3d();\n+        q.mul(-1);\n+        q.add(p);\n+        r.mul(-1);\n+        r.add(p);\n+        q.cross(r, planeNormal);\n+        List<Vector3d> ellipse = intersectionOp.calculate(ellipsoid, new ValuePair<>(interiorPoint, planeNormal));\n+\n+        Vector3dc a0 = ellipse.get(0);\n+        Vector3dc a1 = ellipse.get(1);\n+        Vector3dc a2 = ellipse.get(2);\n+\n+        Matrix4d quadric = new Matrix4d();\n+\n+        //axis and translation contributions calculated with sympy - see documentation\n+        Matrix3d A1 = getAxisContribution(a1);\n+        Matrix3d A2 = getAxisContribution(a2);\n+        A2.add(A1);\n+        quadric.set3x3(A2);\n+\n+        Vector3d translationVector1 = getTranslationContribution(a0, a1);\n+        Vector3d translationVector2 = getTranslationContribution(a0, a2);\n+        translationVector2.add(translationVector1);\n+\n+        quadric.setRow(3, new Vector4d(translationVector2,0));\n+        quadric.setColumn(3, new Vector4d(translationVector2,0));\n+\n+        quadric.m33(getConstantContribution(a0,a1)+getConstantContribution(a0,a2)-1.0);\n+\n+        return quadric;\n+    }\n+\n+    private static Vector3d getTranslationContribution(final Vector3dc centre, final Vector3dc axis) {\n+\n+        double radius = axis.length();\n+\n+        Vector3d unitAxis = new Vector3d(axis);\n+        unitAxis.normalize();\n+\n+        Vector3d translationVector = new Vector3d();\n+\n+        translationVector.x = -unitAxis.x * centre.dot(unitAxis);\n+        translationVector.y = -unitAxis.y * centre.dot(unitAxis);\n+        translationVector.z = -unitAxis.z * centre.dot(unitAxis);\n+\n+        translationVector.mul(1.0 / (radius * radius));\n+\n+        return translationVector;\n+    }\n+\n+    private static double getConstantContribution(final Vector3dc centre, final Vector3dc axis) {\n+        double radius = axis.length();\n+\n+        Vector3d unitAxis = new Vector3d(axis);\n+        unitAxis.normalize();\n+\n+        double constantComponent = centre.x() * centre.x() * unitAxis.x * unitAxis.x;\n+        constantComponent +=centre.y()*centre.y()*unitAxis.y*unitAxis.y;\n+        constantComponent +=centre.z()*centre.z()*unitAxis.z*unitAxis.z;\n+\n+        constantComponent +=2.0*centre.x()*centre.y()*unitAxis.x*unitAxis.y;\n+        constantComponent +=2.0*centre.x()*centre.z()*unitAxis.x*unitAxis.z;\n+        constantComponent +=2.0*centre.y()*centre.z()*unitAxis.y*unitAxis.z;\n+\n+        return constantComponent/(radius*radius);\n+    }\n+\n+    private static Matrix3d getAxisContribution(final Vector3dc axis) {\n+        double radius = axis.length();\n+        Vector3d normalizedAxis = new Vector3d(axis);\n+        normalizedAxis.normalize();\n+\n+        Matrix3d axisContribution = new Matrix3d();\n+        axisContribution.m00(normalizedAxis.x()*normalizedAxis.x()/(radius*radius));\n+        axisContribution.m11(normalizedAxis.y()*normalizedAxis.y()/(radius*radius));\n+        axisContribution.m22(normalizedAxis.z()*normalizedAxis.z()/(radius*radius));\n+\n+        axisContribution.m01(normalizedAxis.x()*normalizedAxis.y()/(radius*radius));\n+        axisContribution.m10(normalizedAxis.x()*normalizedAxis.y()/(radius*radius));\n+\n+        axisContribution.m02(normalizedAxis.x()*normalizedAxis.z()/(radius*radius));\n+        axisContribution.m20(normalizedAxis.x()*normalizedAxis.z()/(radius*radius));\n+\n+        axisContribution.m12(normalizedAxis.y()*normalizedAxis.z()/(radius*radius));\n+        axisContribution.m21(normalizedAxis.y()*normalizedAxis.z()/(radius*radius));\n+\n+        return axisContribution;\n+    }\n+\n+\n+    private static ValuePair<VertexWithNormal,Double> calculateQ(final List<Vector3d> candidateQs, final VertexWithNormal p) {\n+        List<ValuePair<VertexWithNormal, Double>> candidateQAndRs = candidateQs.stream().map(q -> calculatePossibleQAndR(q,p)).filter(qnr -> qnr.getB()>0).collect(Collectors.toList());\n+\n+        candidateQAndRs.sort(Comparator.comparingDouble(ValuePair::getB));\n+\n+        if(candidateQAndRs.size() > 0)\n+            return candidateQAndRs.get(0);\n+        else\n+            return null;\n+    }\n+\n+    private static double euclideanDistance(Vector3d q, Vector3d p) {\n+        Vector3d distance = new Vector3d(q);","path":"Modern/ops/src/main/java/org/bonej/ops/ellipsoid/FindEllipsoidFromBoundaryPoints.java","position":269,"original_position":269,"commit_id":"0eade6d3d1b3ba99e129ae77a2753083afce812a","original_commit_id":"0eade6d3d1b3ba99e129ae77a2753083afce812a","user":{"login":"rimadoma","id":14994878,"node_id":"MDQ6VXNlcjE0OTk0ODc4","avatar_url":"https://avatars0.githubusercontent.com/u/14994878?v=4","gravatar_id":"","url":"https://api.github.com/users/rimadoma","html_url":"https://github.com/rimadoma","followers_url":"https://api.github.com/users/rimadoma/followers","following_url":"https://api.github.com/users/rimadoma/following{/other_user}","gists_url":"https://api.github.com/users/rimadoma/gists{/gist_id}","starred_url":"https://api.github.com/users/rimadoma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rimadoma/subscriptions","organizations_url":"https://api.github.com/users/rimadoma/orgs","repos_url":"https://api.github.com/users/rimadoma/repos","events_url":"https://api.github.com/users/rimadoma/events{/privacy}","received_events_url":"https://api.github.com/users/rimadoma/received_events","type":"User","site_admin":false},"body":"Use `Vector3d.distance(Vector3d)`","created_at":"2018-09-13T13:33:55Z","updated_at":"2018-09-13T13:52:25Z","html_url":"https://github.com/bonej-org/BoneJ2/pull/137#discussion_r217384681","pull_request_url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/comments/217384681"},"html":{"href":"https://github.com/bonej-org/BoneJ2/pull/137#discussion_r217384681"},"pull_request":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137"}}},"pull_request":{"url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137","id":214382774,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE0MzgyNzc0","html_url":"https://github.com/bonej-org/BoneJ2/pull/137","diff_url":"https://github.com/bonej-org/BoneJ2/pull/137.diff","patch_url":"https://github.com/bonej-org/BoneJ2/pull/137.patch","issue_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues/137","number":137,"state":"open","locked":false,"title":"add ellipse-plane intersection op","user":{"login":"alessandrofelder","id":10500965,"node_id":"MDQ6VXNlcjEwNTAwOTY1","avatar_url":"https://avatars1.githubusercontent.com/u/10500965?v=4","gravatar_id":"","url":"https://api.github.com/users/alessandrofelder","html_url":"https://github.com/alessandrofelder","followers_url":"https://api.github.com/users/alessandrofelder/followers","following_url":"https://api.github.com/users/alessandrofelder/following{/other_user}","gists_url":"https://api.github.com/users/alessandrofelder/gists{/gist_id}","starred_url":"https://api.github.com/users/alessandrofelder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alessandrofelder/subscriptions","organizations_url":"https://api.github.com/users/alessandrofelder/orgs","repos_url":"https://api.github.com/users/alessandrofelder/repos","events_url":"https://api.github.com/users/alessandrofelder/events{/privacy}","received_events_url":"https://api.github.com/users/alessandrofelder/received_events","type":"User","site_admin":false},"body":"first step of adding all ellipsoid factor 2 functionality to the jomlize branch.\r\n\r\nthis PR adds the possibility to find the ellipse that is the intersection between an ellipsoid and a plane. The mathematics behind it is explained in http://file.scirp.org/pdf/AM20121100009_89014420.pdf this is useful to implement the ellipsoid fitting outline in https://www.graphics.rwth-aachen.de/media/papers/ellipsoids1.pdf","created_at":"2018-09-10T17:07:56Z","updated_at":"2018-09-13T13:52:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6d8ed5bff2f68c8f7600dd20af06e81bc68f3be9","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137/commits","review_comments_url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137/comments","review_comment_url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues/137/comments","statuses_url":"https://api.github.com/repos/bonej-org/BoneJ2/statuses/0eade6d3d1b3ba99e129ae77a2753083afce812a","head":{"label":"bonej-org:ellipsoid-factor-clean","ref":"ellipsoid-factor-clean","sha":"0eade6d3d1b3ba99e129ae77a2753083afce812a","user":{"login":"bonej-org","id":15815050,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1ODE1MDUw","avatar_url":"https://avatars1.githubusercontent.com/u/15815050?v=4","gravatar_id":"","url":"https://api.github.com/users/bonej-org","html_url":"https://github.com/bonej-org","followers_url":"https://api.github.com/users/bonej-org/followers","following_url":"https://api.github.com/users/bonej-org/following{/other_user}","gists_url":"https://api.github.com/users/bonej-org/gists{/gist_id}","starred_url":"https://api.github.com/users/bonej-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bonej-org/subscriptions","organizations_url":"https://api.github.com/users/bonej-org/orgs","repos_url":"https://api.github.com/users/bonej-org/repos","events_url":"https://api.github.com/users/bonej-org/events{/privacy}","received_events_url":"https://api.github.com/users/bonej-org/received_events","type":"Organization","site_admin":false},"repo":{"id":54976745,"node_id":"MDEwOlJlcG9zaXRvcnk1NDk3Njc0NQ==","name":"BoneJ2","full_name":"bonej-org/BoneJ2","owner":{"login":"bonej-org","id":15815050,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1ODE1MDUw","avatar_url":"https://avatars1.githubusercontent.com/u/15815050?v=4","gravatar_id":"","url":"https://api.github.com/users/bonej-org","html_url":"https://github.com/bonej-org","followers_url":"https://api.github.com/users/bonej-org/followers","following_url":"https://api.github.com/users/bonej-org/following{/other_user}","gists_url":"https://api.github.com/users/bonej-org/gists{/gist_id}","starred_url":"https://api.github.com/users/bonej-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bonej-org/subscriptions","organizations_url":"https://api.github.com/users/bonej-org/orgs","repos_url":"https://api.github.com/users/bonej-org/repos","events_url":"https://api.github.com/users/bonej-org/events{/privacy}","received_events_url":"https://api.github.com/users/bonej-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bonej-org/BoneJ2","description":"BoneJ2 - the next gen version of BoneJ in development","fork":false,"url":"https://api.github.com/repos/bonej-org/BoneJ2","forks_url":"https://api.github.com/repos/bonej-org/BoneJ2/forks","keys_url":"https://api.github.com/repos/bonej-org/BoneJ2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bonej-org/BoneJ2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bonej-org/BoneJ2/teams","hooks_url":"https://api.github.com/repos/bonej-org/BoneJ2/hooks","issue_events_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues/events{/number}","events_url":"https://api.github.com/repos/bonej-org/BoneJ2/events","assignees_url":"https://api.github.com/repos/bonej-org/BoneJ2/assignees{/user}","branches_url":"https://api.github.com/repos/bonej-org/BoneJ2/branches{/branch}","tags_url":"https://api.github.com/repos/bonej-org/BoneJ2/tags","blobs_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/refs{/sha}","trees_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bonej-org/BoneJ2/statuses/{sha}","languages_url":"https://api.github.com/repos/bonej-org/BoneJ2/languages","stargazers_url":"https://api.github.com/repos/bonej-org/BoneJ2/stargazers","contributors_url":"https://api.github.com/repos/bonej-org/BoneJ2/contributors","subscribers_url":"https://api.github.com/repos/bonej-org/BoneJ2/subscribers","subscription_url":"https://api.github.com/repos/bonej-org/BoneJ2/subscription","commits_url":"https://api.github.com/repos/bonej-org/BoneJ2/commits{/sha}","git_commits_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/commits{/sha}","comments_url":"https://api.github.com/repos/bonej-org/BoneJ2/comments{/number}","issue_comment_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues/comments{/number}","contents_url":"https://api.github.com/repos/bonej-org/BoneJ2/contents/{+path}","compare_url":"https://api.github.com/repos/bonej-org/BoneJ2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bonej-org/BoneJ2/merges","archive_url":"https://api.github.com/repos/bonej-org/BoneJ2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bonej-org/BoneJ2/downloads","issues_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues{/number}","pulls_url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls{/number}","milestones_url":"https://api.github.com/repos/bonej-org/BoneJ2/milestones{/number}","notifications_url":"https://api.github.com/repos/bonej-org/BoneJ2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bonej-org/BoneJ2/labels{/name}","releases_url":"https://api.github.com/repos/bonej-org/BoneJ2/releases{/id}","deployments_url":"https://api.github.com/repos/bonej-org/BoneJ2/deployments","created_at":"2016-03-29T13:11:24Z","updated_at":"2018-09-12T12:00:21Z","pushed_at":"2018-09-13T12:47:07Z","git_url":"git://github.com/bonej-org/BoneJ2.git","ssh_url":"git@github.com:bonej-org/BoneJ2.git","clone_url":"https://github.com/bonej-org/BoneJ2.git","svn_url":"https://github.com/bonej-org/BoneJ2","homepage":null,"size":2163,"stargazers_count":5,"watchers_count":5,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":3,"open_issues":12,"watchers":5,"default_branch":"master"}},"base":{"label":"bonej-org:jomlize","ref":"jomlize","sha":"3853b4950472a9d72646f6a69cb1ead4661f4f7e","user":{"login":"bonej-org","id":15815050,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1ODE1MDUw","avatar_url":"https://avatars1.githubusercontent.com/u/15815050?v=4","gravatar_id":"","url":"https://api.github.com/users/bonej-org","html_url":"https://github.com/bonej-org","followers_url":"https://api.github.com/users/bonej-org/followers","following_url":"https://api.github.com/users/bonej-org/following{/other_user}","gists_url":"https://api.github.com/users/bonej-org/gists{/gist_id}","starred_url":"https://api.github.com/users/bonej-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bonej-org/subscriptions","organizations_url":"https://api.github.com/users/bonej-org/orgs","repos_url":"https://api.github.com/users/bonej-org/repos","events_url":"https://api.github.com/users/bonej-org/events{/privacy}","received_events_url":"https://api.github.com/users/bonej-org/received_events","type":"Organization","site_admin":false},"repo":{"id":54976745,"node_id":"MDEwOlJlcG9zaXRvcnk1NDk3Njc0NQ==","name":"BoneJ2","full_name":"bonej-org/BoneJ2","owner":{"login":"bonej-org","id":15815050,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1ODE1MDUw","avatar_url":"https://avatars1.githubusercontent.com/u/15815050?v=4","gravatar_id":"","url":"https://api.github.com/users/bonej-org","html_url":"https://github.com/bonej-org","followers_url":"https://api.github.com/users/bonej-org/followers","following_url":"https://api.github.com/users/bonej-org/following{/other_user}","gists_url":"https://api.github.com/users/bonej-org/gists{/gist_id}","starred_url":"https://api.github.com/users/bonej-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bonej-org/subscriptions","organizations_url":"https://api.github.com/users/bonej-org/orgs","repos_url":"https://api.github.com/users/bonej-org/repos","events_url":"https://api.github.com/users/bonej-org/events{/privacy}","received_events_url":"https://api.github.com/users/bonej-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bonej-org/BoneJ2","description":"BoneJ2 - the next gen version of BoneJ in development","fork":false,"url":"https://api.github.com/repos/bonej-org/BoneJ2","forks_url":"https://api.github.com/repos/bonej-org/BoneJ2/forks","keys_url":"https://api.github.com/repos/bonej-org/BoneJ2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bonej-org/BoneJ2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bonej-org/BoneJ2/teams","hooks_url":"https://api.github.com/repos/bonej-org/BoneJ2/hooks","issue_events_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues/events{/number}","events_url":"https://api.github.com/repos/bonej-org/BoneJ2/events","assignees_url":"https://api.github.com/repos/bonej-org/BoneJ2/assignees{/user}","branches_url":"https://api.github.com/repos/bonej-org/BoneJ2/branches{/branch}","tags_url":"https://api.github.com/repos/bonej-org/BoneJ2/tags","blobs_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/refs{/sha}","trees_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bonej-org/BoneJ2/statuses/{sha}","languages_url":"https://api.github.com/repos/bonej-org/BoneJ2/languages","stargazers_url":"https://api.github.com/repos/bonej-org/BoneJ2/stargazers","contributors_url":"https://api.github.com/repos/bonej-org/BoneJ2/contributors","subscribers_url":"https://api.github.com/repos/bonej-org/BoneJ2/subscribers","subscription_url":"https://api.github.com/repos/bonej-org/BoneJ2/subscription","commits_url":"https://api.github.com/repos/bonej-org/BoneJ2/commits{/sha}","git_commits_url":"https://api.github.com/repos/bonej-org/BoneJ2/git/commits{/sha}","comments_url":"https://api.github.com/repos/bonej-org/BoneJ2/comments{/number}","issue_comment_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues/comments{/number}","contents_url":"https://api.github.com/repos/bonej-org/BoneJ2/contents/{+path}","compare_url":"https://api.github.com/repos/bonej-org/BoneJ2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bonej-org/BoneJ2/merges","archive_url":"https://api.github.com/repos/bonej-org/BoneJ2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bonej-org/BoneJ2/downloads","issues_url":"https://api.github.com/repos/bonej-org/BoneJ2/issues{/number}","pulls_url":"https://api.github.com/repos/bonej-org/BoneJ2/pulls{/number}","milestones_url":"https://api.github.com/repos/bonej-org/BoneJ2/milestones{/number}","notifications_url":"https://api.github.com/repos/bonej-org/BoneJ2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bonej-org/BoneJ2/labels{/name}","releases_url":"https://api.github.com/repos/bonej-org/BoneJ2/releases{/id}","deployments_url":"https://api.github.com/repos/bonej-org/BoneJ2/deployments","created_at":"2016-03-29T13:11:24Z","updated_at":"2018-09-12T12:00:21Z","pushed_at":"2018-09-13T12:47:07Z","git_url":"git://github.com/bonej-org/BoneJ2.git","ssh_url":"git@github.com:bonej-org/BoneJ2.git","clone_url":"https://github.com/bonej-org/BoneJ2.git","svn_url":"https://github.com/bonej-org/BoneJ2","homepage":null,"size":2163,"stargazers_count":5,"watchers_count":5,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":3,"open_issues":12,"watchers":5,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137"},"html":{"href":"https://github.com/bonej-org/BoneJ2/pull/137"},"issue":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/issues/137"},"comments":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/issues/137/comments"},"review_comments":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137/comments"},"review_comment":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/pulls/137/commits"},"statuses":{"href":"https://api.github.com/repos/bonej-org/BoneJ2/statuses/0eade6d3d1b3ba99e129ae77a2753083afce812a"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"rimadoma"}}