reverse non closed shapes fix
diff --git a/extension/jsx/utils/shapeHelper.jsx b/extension/jsx/utils/shapeHelper.jsx
index fb32f8d..c49ee2b 100644
--- a/extension/jsx/utils/shapeHelper.jsx
+++ b/extension/jsx/utils/shapeHelper.jsx
@@ -37,16 +37,21 @@
         }
     }
     
-    function reverseShape(ks) {
+    function reverseShape(ks, isClosed) {
         var newI = [], newO = [], newV = [];
         var i, len;
         if (ks.i) {
-            newI[0] = ks.o[0];
-            newO[0] = ks.i[0];
-            newV[0] = ks.v[0];
+            var init = 0;
+            if (isClosed) {
+                newI[0] = ks.o[0];
+                newO[0] = ks.i[0];
+                newV[0] = ks.v[0];
+                init = 1;
+            }
             len = ks.i.length;
             var cnt = len - 1;
-            for (i = 1; i < len; i += 1) {
+            
+            for (i = init; i < len; i += 1) {
                 newI.push(ks.o[cnt]);
                 newO.push(ks.i[cnt]);
                 newV.push(ks.v[cnt]);
@@ -59,8 +64,8 @@
         } else {
             len = ks.length;
             for (i = 0; i < len - 1; i += 1) {
-                reverseShape(ks[i].s[0]);
-                reverseShape(ks[i].e[0]);
+                reverseShape(ks[i].s[0], isClosed);
+                reverseShape(ks[i].e[0], isClosed);
             }
         }
     }
@@ -77,7 +82,7 @@
                     ob.closed = prop.property('Path').value.closed;
                     ob.ks = bm_keyframeHelper.exportKeyframes(prop.property('Path'), frameRate);
                     if (prop.property("Shape Direction").value === 3) {
-                        reverseShape(ob.ks);
+                        reverseShape(ob.ks, ob.closed);
                     }
                     array.push(ob);
                 } else if (itemType === shapeItemTypes.rect) {
diff --git a/player/index.html b/player/index.html
index c90b7fe..35bc255 100644
--- a/player/index.html
+++ b/player/index.html
@@ -40,7 +40,7 @@
 <body style="background-color:#ccc; margin: 0px;height: 100%; font-family: sans-serif;font-size: 10px">
 
 <!-- <div style="width:1350px;height:650px;background-color:#faf5d3;display:inline-block;" class="bodymovin" data-bm-path="exports/render/" data-bm-type="svg" data-bm-loop="true" data-bm-prerender="false"></div> -->
-<div style="width:1500px;height:700px;background-color:#333;display:inline-block;" id="bodymovin"></div>
+<div style="width:800px;height:800px;background-color:#333;display:inline-block;" id="bodymovin"></div>
 
 <script>
 
@@ -55,13 +55,13 @@
     var animData = {
         wrapper: document.getElementById('bodymovin'),
         animType: 'svg',
-        loop: 1,
+        loop: true,
         prerender: false,
         autoplay: true,
         path: 'exports/render'
 
     };
-    bodymovin.setQuality(100);
+    bodymovin.setQuality(50);
     var anim = bodymovin.loadAnimation(animData);
     anim.addEventListener('bm:config_ready', configReady);
     anim.addEventListener('bm:data_ready', dataReady);
diff --git a/player/js/animation/AnimationItem.js b/player/js/animation/AnimationItem.js
index 71c685d..f752f5b 100644
--- a/player/js/animation/AnimationItem.js
+++ b/player/js/animation/AnimationItem.js
@@ -203,8 +203,8 @@
     this.assets = this.animationData.assets;
     this.frameRate = this.animationData.fr;
     this.firstFrame = Math.round(this.animationData.ip*this.frameRate);
-    this.firstFrame = 39;
-    this.totalFrames = 2;
+    /*this.firstFrame = 25;
+    this.totalFrames = 1;*/
     this.frameMult = this.animationData.fr / 1000;
     this.trigger('bm:config_ready');
     this.loadSegments();
diff --git a/player/js/elements/ShapeItemElement.js b/player/js/elements/ShapeItemElement.js
index fff273b..3d38fc5 100644
--- a/player/js/elements/ShapeItemElement.js
+++ b/player/js/elements/ShapeItemElement.js
@@ -180,7 +180,7 @@
         }else if(items[i].ty == 'fl'){
             this.renderFill(items[i],data[i],num,groupTransform);
         }else if(items[i].ty == 'st'){
-            this.renderStroke(items[i],data[i],num);
+            this.renderStroke(items[i],data[i],num,groupTransform);
         }else if(items[i].ty == 'gr'){
             this.renderShape(num,groupTransform,items[i].it,data[i].it);
         }else if(items[i].ty == 'tm'){
@@ -213,77 +213,75 @@
     if(!viewData.renderedFrames[this.globalData.frameNum]){
 
         var pathNodes = pathData.renderedData[num].path.pathNodes;
-        if(!pathNodes.v){
-            return;
-        }
-        len = pathNodes.v.length;
-        var stops = pathNodes.s ? pathNodes.s : [];
+        var t = '';
         var pathStringTransformed = '';
         var pathStringNonTransformed = '';
-        for(i=1;i<len;i+=1){
-            if(stops[i-1]){
-                if(viewData.st){
-                    pathStringNonTransformed += " M"+bm_rnd(stops[i-1][0])+','+bm_rnd(stops[i-1][1]);
+        if(pathNodes.v){
+            len = pathNodes.v.length;
+            var stops = pathNodes.s ? pathNodes.s : [];
+            for(i=1;i<len;i+=1){
+                if(stops[i-1]){
+                    if(viewData.st){
+                        pathStringNonTransformed += " M"+bm_rnd(stops[i-1][0])+','+bm_rnd(stops[i-1][1]);
+                    }
+                    if(viewData.fl) {
+                        pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(stops[i - 1][0], stops[i - 1][1]);
+                    }
+                }else if(i==1){
+                    if(viewData.st) {
+                        pathStringNonTransformed += " M" + bm_rnd(pathNodes.v[0][0]) + ',' + bm_rnd(pathNodes.v[0][1]);
+                    }
+
+                    if(viewData.fl) {
+                        pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                    }
                 }
-                if(viewData.fl) {
-                    pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(stops[i - 1][0], stops[i - 1][1]);
-                }
-            }else if(i==1){
                 if(viewData.st) {
-                    pathStringNonTransformed += " M" + bm_rnd(pathNodes.v[0][0]) + ',' + bm_rnd(pathNodes.v[0][1]);
+                    pathStringNonTransformed += " C" + bm_rnd(pathNodes.o[i - 1][0]) + ',' + bm_rnd(pathNodes.o[i - 1][1]) + " " + bm_rnd(pathNodes.i[i][0]) + ',' + bm_rnd(pathNodes.i[i][1]) + " " + bm_rnd(pathNodes.v[i][0]) + ',' + bm_rnd(pathNodes.v[i][1]);
                 }
 
                 if(viewData.fl) {
-                    pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                    pathStringTransformed += " C" + groupTransform.mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.i[i][0], pathNodes.i[i][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.v[i][0], pathNodes.v[i][1]);
+                }
+            }
+            if(len == 1){
+                if(stops[0]){
+                    if(viewData.st) {
+                        pathStringNonTransformed += " M" + bm_rnd(stops[0][0]) + ',' + bm_rnd(stops[0][1]);
+                    }
+
+                    if(viewData.fl) {
+                        pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(stops[0][0], stops[0][1]);
+                    }
+                }else{
+
+                    if(viewData.st) {
+                        pathStringNonTransformed += " M" + bm_rnd(pathNodes.v[0][0]) + ',' + bm_rnd(pathNodes.v[0][1]);
+                    }
+
+                    if(viewData.fl) {
+                        pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                    }
+                }
+            }
+            if(pathData.closed && !(pathData.trimmed && !pathNodes.c)){
+                if(viewData.st) {
+                    pathStringNonTransformed += " C" + bm_rnd(pathNodes.o[i - 1][0]) + ',' + bm_rnd(pathNodes.o[i - 1][1]) + " " + bm_rnd(pathNodes.i[0][0]) + ',' + bm_rnd(pathNodes.i[0][1]) + " " + bm_rnd(pathNodes.v[0][0]) + ',' + bm_rnd(pathNodes.v[0][1]);
+                }
+
+                if(viewData.fl) {
+                    pathStringTransformed += " C" + groupTransform.mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.i[0][0], pathNodes.i[0][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
                 }
             }
             if(viewData.st) {
-                pathStringNonTransformed += " C" + bm_rnd(pathNodes.o[i - 1][0]) + ',' + bm_rnd(pathNodes.o[i - 1][1]) + " " + bm_rnd(pathNodes.i[i][0]) + ',' + bm_rnd(pathNodes.i[i][1]) + " " + bm_rnd(pathNodes.v[i][0]) + ',' + bm_rnd(pathNodes.v[i][1]);
+                t = 'matrix(' + groupTransform.mat.props.join(',') + ')';
             }
-
-            if(viewData.fl) {
-                pathStringTransformed += " C" + groupTransform.mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.i[i][0], pathNodes.i[i][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.v[i][0], pathNodes.v[i][1]);
-            }
-        }
-        if(len == 1){
-            if(stops[0]){
-                if(viewData.st) {
-                    pathStringNonTransformed += " M" + bm_rnd(stops[0][0]) + ',' + bm_rnd(stops[0][1]);
-                }
-
-                if(viewData.fl) {
-                    pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(stops[0][0], stops[0][1]);
-                }
-            }else{
-
-                if(viewData.st) {
-                    pathStringNonTransformed += " M" + bm_rnd(pathNodes.v[0][0]) + ',' + bm_rnd(pathNodes.v[0][1]);
-                }
-
-                if(viewData.fl) {
-                    pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
-                }
-            }
-        }
-        if(pathData.closed && !(pathData.trimmed && !pathNodes.c)){
-            if(viewData.st) {
-                pathStringNonTransformed += " C" + bm_rnd(pathNodes.o[i - 1][0]) + ',' + bm_rnd(pathNodes.o[i - 1][1]) + " " + bm_rnd(pathNodes.i[0][0]) + ',' + bm_rnd(pathNodes.i[0][1]) + " " + bm_rnd(pathNodes.v[0][0]) + ',' + bm_rnd(pathNodes.v[0][1]);
-            }
-
-            if(viewData.fl) {
-                pathStringTransformed += " C" + groupTransform.mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.i[0][0], pathNodes.i[0][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
-            }
-        }
-        var t;
-        if(viewData.st) {
-            t = 'matrix(' + groupTransform.mat.props.join(',') + ')';
         }
 
         viewData.renderedFrames[this.globalData.frameNum] = {
             dTr: pathStringTransformed,
             dNTr: pathStringNonTransformed,
-            t: t,
-            o: groupTransform.opacity
+            t: t
         };
     }
     var renderedFrameData = viewData.renderedFrames[this.globalData.frameNum];
@@ -298,14 +296,8 @@
                 viewData.elements[i].el.setAttribute('transform',renderedFrameData.t);
                 viewData.lt = renderedFrameData.t;
             }
-            if(viewData.lo != renderedFrameData.o) {
-                viewData.elements[i].el.setAttribute('opacity',renderedFrameData.o);
-                viewData.lo = renderedFrameData.o;
-            }
         }else{
-            if(renderedFrameData.o !== 0){
-                viewData.elements[i].st.d += renderedFrameData.dTr;
-            }
+            viewData.elements[i].st.d += renderedFrameData.dTr;
         }
     }
 };
@@ -337,17 +329,17 @@
     }
 };
 
-ShapeItemElement.prototype.renderStroke = function(styleData,viewData,num){
+ShapeItemElement.prototype.renderStroke = function(styleData,viewData,num, groupTransform){
     var fillData = styleData.renderedData[num];
     var styleElem = viewData.style;
     if(!viewData.renderedFrames[this.globalData.frameNum]){
-        if(viewData._ld && viewData._ld.c === fillData.color && viewData._ld.o === fillData.opacity && viewData._ld.w === fillData.width){
+        if(viewData._ld && viewData._ld.c === fillData.color && viewData._ld.o === fillData.opacity*groupTransform.opacity && viewData._ld.w === fillData.width){
             viewData.renderedFrames[this.globalData.frameNum] = viewData._ld;
             return;
         }else{
             viewData._ld = {
                 c: fillData.color,
-                o: fillData.opacity,
+                o: fillData.opacity*groupTransform.opacity,
                 w: fillData.width
             };
             viewData.renderedFrames[this.globalData.frameNum] = viewData._ld;