UNPKG

videojs-vr

Version:

A plugin to add 360 and VR video support to video.js.

81 lines 702 kB
/*! @name videojs-vr @version 2.0.0 @license MIT */ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).videojsVr=e(t.videojs)}(this,(function(t){"use strict";function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t);const i=function(){return/Android/i.test(navigator.userAgent)||/iPhone|iPad|iPod/i.test(navigator.userAgent)},r=function(t,e){for(var n=0,i=t.length;n<i;n++)e[n]=t[n]},o=function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t};var s="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function a(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var l={exports:{}}; /** * @license * cardboard-vr-display * Copyright (c) 2015-2017 Google * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */!function(t,e){ /** * @license * gl-preserve-state * Copyright (c) 2016, Brandon Jones. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /** * @license * webvr-polyfill-dpdb * Copyright (c) 2015-2017 Google * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @license * nosleep.js * Copyright (c) 2017, Rich Tibbett * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ t.exports=function(){var t,e,n,i=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},r=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),o=function(){function t(t,e){var n=[],i=!0,r=!1,o=void 0;try{for(var s,a=t[Symbol.iterator]();!(i=(s=a.next()).done)&&(n.push(s.value),!e||n.length!==e);i=!0);}catch(t){r=!0,o=t}finally{try{!i&&a.return&&a.return()}finally{if(r)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=.001,l=1,c=function(t,e){return"data:"+t+","+encodeURIComponent(e)},h=function(t,e,n){return t+(e-t)*n},u=function(){var t=/iPad|iPhone|iPod/.test(navigator.platform);return function(){return t}}(),d=function(){var t=-1!==navigator.userAgent.indexOf("Version")&&-1!==navigator.userAgent.indexOf("Android")&&-1!==navigator.userAgent.indexOf("Chrome");return function(){return t}}(),p=function(){var t=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);return function(){return t}}(),f=function(){var t=-1!==navigator.userAgent.indexOf("Firefox")&&-1!==navigator.userAgent.indexOf("Android");return function(){return t}}(),m=(e=navigator.userAgent.match(/.*Chrome\/([0-9]+)/),n=e?parseInt(e[1],10):null,function(){return n}),g=function(){var t=!1;return t=u()&&p()&&-1!==navigator.userAgent.indexOf("13_4"),function(){return t}}(),v=function(){var t=!1;if(65===m()){var e=navigator.userAgent.match(/.*Chrome\/([0-9\.]*)/);if(e){var n=e[1].split("."),i=o(n,4);i[0],i[1];var r=i[2],s=i[3];t=3325===parseInt(r,10)&&parseInt(s,10)<148}}return function(){return t}}(),y=function(){var t=-1!==navigator.userAgent.indexOf("R7 Build");return function(){return t}}(),A=function(){var t=90==window.orientation||-90==window.orientation;return y()?!t:t},x=function(t){return!(isNaN(t)||t<=a||t>l)},_=function(){return Math.max(window.screen.width,window.screen.height)*window.devicePixelRatio},w=function(){return Math.min(window.screen.width,window.screen.height)*window.devicePixelRatio},b=function(t){if(d())return!1;if(t.requestFullscreen)t.requestFullscreen();else if(t.webkitRequestFullscreen)t.webkitRequestFullscreen();else if(t.mozRequestFullScreen)t.mozRequestFullScreen();else{if(!t.msRequestFullscreen)return!1;t.msRequestFullscreen()}return!0},M=function(){if(document.exitFullscreen)document.exitFullscreen();else if(document.webkitExitFullscreen)document.webkitExitFullscreen();else if(document.mozCancelFullScreen)document.mozCancelFullScreen();else{if(!document.msExitFullscreen)return!1;document.msExitFullscreen()}return!0},E=function(){return document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement},S=function(t,e,n,i){var r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,e),t.compileShader(r);var o=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(o,n),t.compileShader(o);var s=t.createProgram();for(var a in t.attachShader(s,r),t.attachShader(s,o),i)t.bindAttribLocation(s,i[a],a);return t.linkProgram(s),t.deleteShader(r),t.deleteShader(o),s},T=function(t,e){for(var n={},i=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),r="",o=0;o<i;o++)n[r=t.getActiveUniform(e,o).name.replace("[0]","")]=t.getUniformLocation(e,r);return n},L=function(t,e,n,i,r,o,s){var a=1/(e-n),l=1/(i-r),c=1/(o-s);return t[0]=-2*a,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*l,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*c,t[11]=0,t[12]=(e+n)*a,t[13]=(r+i)*l,t[14]=(s+o)*c,t[15]=1,t},R=function(){var t,e=!1;return t=navigator.userAgent||navigator.vendor||window.opera,(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0),e},C=function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},P=function(t){if(u()){var e=t.style.width,n=t.style.height;t.style.width=parseInt(e)+1+"px",t.style.height=parseInt(n)+"px",setTimeout((function(){t.style.width=e,t.style.height=n}),100)}window.canvas=t},D=function(){var t=Math.PI/180,e=.25*Math.PI;function n(n,i,r,o){var s=Math.tan(i?i.upDegrees*t:e),a=Math.tan(i?i.downDegrees*t:e),l=Math.tan(i?i.leftDegrees*t:e),c=Math.tan(i?i.rightDegrees*t:e),h=2/(l+c),u=2/(s+a);return n[0]=h,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=u,n[6]=0,n[7]=0,n[8]=-(l-c)*h*.5,n[9]=(s-a)*u*.5,n[10]=o/(r-o),n[11]=-1,n[12]=0,n[13]=0,n[14]=o*r/(r-o),n[15]=0,n}function i(t,e,n){var i=e[0],r=e[1],o=e[2],s=e[3],a=i+i,l=r+r,c=o+o,h=i*a,u=i*l,d=i*c,p=r*l,f=r*c,m=o*c,g=s*a,v=s*l,y=s*c;return t[0]=1-(p+m),t[1]=u+y,t[2]=d-v,t[3]=0,t[4]=u-y,t[5]=1-(h+m),t[6]=f+g,t[7]=0,t[8]=d+v,t[9]=f-g,t[10]=1-(h+p),t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t}function r(t,e,n){var i,r,o,s,a,l,c,h,u,d,p,f,m=n[0],g=n[1],v=n[2];return e===t?(t[12]=e[0]*m+e[4]*g+e[8]*v+e[12],t[13]=e[1]*m+e[5]*g+e[9]*v+e[13],t[14]=e[2]*m+e[6]*g+e[10]*v+e[14],t[15]=e[3]*m+e[7]*g+e[11]*v+e[15]):(i=e[0],r=e[1],o=e[2],s=e[3],a=e[4],l=e[5],c=e[6],h=e[7],u=e[8],d=e[9],p=e[10],f=e[11],t[0]=i,t[1]=r,t[2]=o,t[3]=s,t[4]=a,t[5]=l,t[6]=c,t[7]=h,t[8]=u,t[9]=d,t[10]=p,t[11]=f,t[12]=i*m+a*g+u*v+e[12],t[13]=r*m+l*g+d*v+e[13],t[14]=o*m+c*g+p*v+e[14],t[15]=s*m+h*g+f*v+e[15]),t}function o(t,e){var n=e[0],i=e[1],r=e[2],o=e[3],s=e[4],a=e[5],l=e[6],c=e[7],h=e[8],u=e[9],d=e[10],p=e[11],f=e[12],m=e[13],g=e[14],v=e[15],y=n*a-i*s,A=n*l-r*s,x=n*c-o*s,_=i*l-r*a,w=i*c-o*a,b=r*c-o*l,M=h*m-u*f,E=h*g-d*f,S=h*v-p*f,T=u*g-d*m,L=u*v-p*m,R=d*v-p*g,C=y*R-A*L+x*T+_*S-w*E+b*M;return C?(C=1/C,t[0]=(a*R-l*L+c*T)*C,t[1]=(r*L-i*R-o*T)*C,t[2]=(m*b-g*w+v*_)*C,t[3]=(d*w-u*b-p*_)*C,t[4]=(l*S-s*R-c*E)*C,t[5]=(n*R-r*S+o*E)*C,t[6]=(g*x-f*b-v*A)*C,t[7]=(h*b-d*x+p*A)*C,t[8]=(s*L-a*S+c*M)*C,t[9]=(i*S-n*L-o*M)*C,t[10]=(f*w-m*x+v*y)*C,t[11]=(u*x-h*w-p*y)*C,t[12]=(a*E-s*T-l*M)*C,t[13]=(n*T-i*E+r*M)*C,t[14]=(m*A-f*_-g*y)*C,t[15]=(h*_-u*A+d*y)*C,t):null}var s=new Float32Array([0,0,0,1]),a=new Float32Array([0,0,0]);function l(t,e,l,c,h,u){n(t,c||null,u.depthNear,u.depthFar),i(e,l.orientation||s,l.position||a),h&&r(e,e,h),o(e,e)}return function(t,e,n){return!(!t||!e||(t.pose=e,t.timestamp=e.timestamp,l(t.leftProjectionMatrix,t.leftViewMatrix,e,n._getFieldOfView("left"),n._getEyeOffset("left"),n),l(t.rightProjectionMatrix,t.rightViewMatrix,e,n._getFieldOfView("right"),n._getEyeOffset("right"),n),0))}}(),I=function(){var t=window.self!==window.top,e=N(document.referrer),n=N(window.location.href);return t&&e!==n},N=function(t){var e,n=t.indexOf("://");e=-1!==n?n+3:0;var i=t.indexOf("/",e);return-1===i&&(i=t.length),t.substring(0,i)},O=function(t){return t.w>1?(console.warn("getQuaternionAngle: w > 1"),0):2*Math.acos(t.w)},B=(t={},function(e,n){void 0===t[e]&&(console.warn("webvr-polyfill: "+n),t[e]=!0)}),F=function(t,e){B(t,t+" has been deprecated. This may not work on native WebVR displays. "+(e?"Please use "+e+" instead.":""))};function z(t,e,n){if(e){for(var i=[],r=null,o=0;o<e.length;++o)switch(s=e[o]){case t.TEXTURE_BINDING_2D:case t.TEXTURE_BINDING_CUBE_MAP:if((l=e[++o])<t.TEXTURE0||l>t.TEXTURE31){console.error("TEXTURE_BINDING_2D or TEXTURE_BINDING_CUBE_MAP must be followed by a valid texture unit"),i.push(null,null);break}r||(r=t.getParameter(t.ACTIVE_TEXTURE)),t.activeTexture(l),i.push(t.getParameter(s),null);break;case t.ACTIVE_TEXTURE:r=t.getParameter(t.ACTIVE_TEXTURE),i.push(null);break;default:i.push(t.getParameter(s))}for(n(t),o=0;o<e.length;++o){var s=e[o],a=i[o];switch(s){case t.ACTIVE_TEXTURE:break;case t.ARRAY_BUFFER_BINDING:t.bindBuffer(t.ARRAY_BUFFER,a);break;case t.COLOR_CLEAR_VALUE:t.clearColor(a[0],a[1],a[2],a[3]);break;case t.COLOR_WRITEMASK:t.colorMask(a[0],a[1],a[2],a[3]);break;case t.CURRENT_PROGRAM:t.useProgram(a);break;case t.ELEMENT_ARRAY_BUFFER_BINDING:t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,a);break;case t.FRAMEBUFFER_BINDING:t.bindFramebuffer(t.FRAMEBUFFER,a);break;case t.RENDERBUFFER_BINDING:t.bindRenderbuffer(t.RENDERBUFFER,a);break;case t.TEXTURE_BINDING_2D:if((l=e[++o])<t.TEXTURE0||l>t.TEXTURE31)break;t.activeTexture(l),t.bindTexture(t.TEXTURE_2D,a);break;case t.TEXTURE_BINDING_CUBE_MAP:var l;if((l=e[++o])<t.TEXTURE0||l>t.TEXTURE31)break;t.activeTexture(l),t.bindTexture(t.TEXTURE_CUBE_MAP,a);break;case t.VIEWPORT:t.viewport(a[0],a[1],a[2],a[3]);break;case t.BLEND:case t.CULL_FACE:case t.DEPTH_TEST:case t.SCISSOR_TEST:case t.STENCIL_TEST:a?t.enable(s):t.disable(s);break;default:console.log("No GL restore behavior for 0x"+s.toString(16))}r&&t.activeTexture(r)}}else n(t)}var U=z,H=["attribute vec2 position;","attribute vec3 texCoord;","varying vec2 vTexCoord;","uniform vec4 viewportOffsetScale[2];","void main() {"," vec4 viewport = viewportOffsetScale[int(texCoord.z)];"," vTexCoord = (texCoord.xy * viewport.zw) + viewport.xy;"," gl_Position = vec4( position, 1.0, 1.0 );","}"].join("\n"),G=["precision mediump float;","uniform sampler2D diffuse;","varying vec2 vTexCoord;","void main() {"," gl_FragColor = texture2D(diffuse, vTexCoord);","}"].join("\n");function V(t,e,n,i){this.gl=t,this.cardboardUI=e,this.bufferScale=n,this.dirtySubmitFrameBindings=i,this.ctxAttribs=t.getContextAttributes(),this.instanceExt=t.getExtension("ANGLE_instanced_arrays"),this.meshWidth=20,this.meshHeight=20,this.bufferWidth=t.drawingBufferWidth,this.bufferHeight=t.drawingBufferHeight,this.realBindFramebuffer=t.bindFramebuffer,this.realEnable=t.enable,this.realDisable=t.disable,this.realColorMask=t.colorMask,this.realClearColor=t.clearColor,this.realViewport=t.viewport,u()||(this.realCanvasWidth=Object.getOwnPropertyDescriptor(t.canvas.__proto__,"width"),this.realCanvasHeight=Object.getOwnPropertyDescriptor(t.canvas.__proto__,"height")),this.isPatched=!1,this.lastBoundFramebuffer=null,this.cullFace=!1,this.depthTest=!1,this.blend=!1,this.scissorTest=!1,this.stencilTest=!1,this.viewport=[0,0,0,0],this.colorMask=[!0,!0,!0,!0],this.clearColor=[0,0,0,0],this.attribs={position:0,texCoord:1},this.program=S(t,H,G,this.attribs),this.uniforms=T(t,this.program),this.viewportOffsetScale=new Float32Array(8),this.setTextureBounds(),this.vertexBuffer=t.createBuffer(),this.indexBuffer=t.createBuffer(),this.indexCount=0,this.renderTarget=t.createTexture(),this.framebuffer=t.createFramebuffer(),this.depthStencilBuffer=null,this.depthBuffer=null,this.stencilBuffer=null,this.ctxAttribs.depth&&this.ctxAttribs.stencil?this.depthStencilBuffer=t.createRenderbuffer():this.ctxAttribs.depth?this.depthBuffer=t.createRenderbuffer():this.ctxAttribs.stencil&&(this.stencilBuffer=t.createRenderbuffer()),this.patch(),this.onResize()}V.prototype.destroy=function(){var t=this.gl;this.unpatch(),t.deleteProgram(this.program),t.deleteBuffer(this.vertexBuffer),t.deleteBuffer(this.indexBuffer),t.deleteTexture(this.renderTarget),t.deleteFramebuffer(this.framebuffer),this.depthStencilBuffer&&t.deleteRenderbuffer(this.depthStencilBuffer),this.depthBuffer&&t.deleteRenderbuffer(this.depthBuffer),this.stencilBuffer&&t.deleteRenderbuffer(this.stencilBuffer),this.cardboardUI&&this.cardboardUI.destroy()},V.prototype.onResize=function(){var t=this.gl,e=this,n=[t.RENDERBUFFER_BINDING,t.TEXTURE_BINDING_2D,t.TEXTURE0];U(t,n,(function(t){e.realBindFramebuffer.call(t,t.FRAMEBUFFER,null),e.scissorTest&&e.realDisable.call(t,t.SCISSOR_TEST),e.realColorMask.call(t,!0,!0,!0,!0),e.realViewport.call(t,0,0,t.drawingBufferWidth,t.drawingBufferHeight),e.realClearColor.call(t,0,0,0,1),t.clear(t.COLOR_BUFFER_BIT),e.realBindFramebuffer.call(t,t.FRAMEBUFFER,e.framebuffer),t.bindTexture(t.TEXTURE_2D,e.renderTarget),t.texImage2D(t.TEXTURE_2D,0,e.ctxAttribs.alpha?t.RGBA:t.RGB,e.bufferWidth,e.bufferHeight,0,e.ctxAttribs.alpha?t.RGBA:t.RGB,t.UNSIGNED_BYTE,null),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,e.renderTarget,0),e.ctxAttribs.depth&&e.ctxAttribs.stencil?(t.bindRenderbuffer(t.RENDERBUFFER,e.depthStencilBuffer),t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_STENCIL,e.bufferWidth,e.bufferHeight),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,e.depthStencilBuffer)):e.ctxAttribs.depth?(t.bindRenderbuffer(t.RENDERBUFFER,e.depthBuffer),t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_COMPONENT16,e.bufferWidth,e.bufferHeight),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,e.depthBuffer)):e.ctxAttribs.stencil&&(t.bindRenderbuffer(t.RENDERBUFFER,e.stencilBuffer),t.renderbufferStorage(t.RENDERBUFFER,t.STENCIL_INDEX8,e.bufferWidth,e.bufferHeight),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.STENCIL_ATTACHMENT,t.RENDERBUFFER,e.stencilBuffer)),!t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE&&console.error("Framebuffer incomplete!"),e.realBindFramebuffer.call(t,t.FRAMEBUFFER,e.lastBoundFramebuffer),e.scissorTest&&e.realEnable.call(t,t.SCISSOR_TEST),e.realColorMask.apply(t,e.colorMask),e.realViewport.apply(t,e.viewport),e.realClearColor.apply(t,e.clearColor)})),this.cardboardUI&&this.cardboardUI.onResize()},V.prototype.patch=function(){if(!this.isPatched){var t=this,e=this.gl.canvas,n=this.gl;u()||(e.width=_()*this.bufferScale,e.height=w()*this.bufferScale,Object.defineProperty(e,"width",{configurable:!0,enumerable:!0,get:function(){return t.bufferWidth},set:function(n){t.bufferWidth=n,t.realCanvasWidth.set.call(e,n),t.onResize()}}),Object.defineProperty(e,"height",{configurable:!0,enumerable:!0,get:function(){return t.bufferHeight},set:function(n){t.bufferHeight=n,t.realCanvasHeight.set.call(e,n),t.onResize()}})),this.lastBoundFramebuffer=n.getParameter(n.FRAMEBUFFER_BINDING),null==this.lastBoundFramebuffer&&(this.lastBoundFramebuffer=this.framebuffer,this.gl.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer)),this.gl.bindFramebuffer=function(e,i){t.lastBoundFramebuffer=i||t.framebuffer,t.realBindFramebuffer.call(n,e,t.lastBoundFramebuffer)},this.cullFace=n.getParameter(n.CULL_FACE),this.depthTest=n.getParameter(n.DEPTH_TEST),this.blend=n.getParameter(n.BLEND),this.scissorTest=n.getParameter(n.SCISSOR_TEST),this.stencilTest=n.getParameter(n.STENCIL_TEST),n.enable=function(e){switch(e){case n.CULL_FACE:t.cullFace=!0;break;case n.DEPTH_TEST:t.depthTest=!0;break;case n.BLEND:t.blend=!0;break;case n.SCISSOR_TEST:t.scissorTest=!0;break;case n.STENCIL_TEST:t.stencilTest=!0}t.realEnable.call(n,e)},n.disable=function(e){switch(e){case n.CULL_FACE:t.cullFace=!1;break;case n.DEPTH_TEST:t.depthTest=!1;break;case n.BLEND:t.blend=!1;break;case n.SCISSOR_TEST:t.scissorTest=!1;break;case n.STENCIL_TEST:t.stencilTest=!1}t.realDisable.call(n,e)},this.colorMask=n.getParameter(n.COLOR_WRITEMASK),n.colorMask=function(e,i,r,o){t.colorMask[0]=e,t.colorMask[1]=i,t.colorMask[2]=r,t.colorMask[3]=o,t.realColorMask.call(n,e,i,r,o)},this.clearColor=n.getParameter(n.COLOR_CLEAR_VALUE),n.clearColor=function(e,i,r,o){t.clearColor[0]=e,t.clearColor[1]=i,t.clearColor[2]=r,t.clearColor[3]=o,t.realClearColor.call(n,e,i,r,o)},this.viewport=n.getParameter(n.VIEWPORT),n.viewport=function(e,i,r,o){t.viewport[0]=e,t.viewport[1]=i,t.viewport[2]=r,t.viewport[3]=o,t.realViewport.call(n,e,i,r,o)},this.isPatched=!0,P(e)}},V.prototype.unpatch=function(){if(this.isPatched){var t=this.gl,e=this.gl.canvas;u()||(Object.defineProperty(e,"width",this.realCanvasWidth),Object.defineProperty(e,"height",this.realCanvasHeight)),e.width=this.bufferWidth,e.height=this.bufferHeight,t.bindFramebuffer=this.realBindFramebuffer,t.enable=this.realEnable,t.disable=this.realDisable,t.colorMask=this.realColorMask,t.clearColor=this.realClearColor,t.viewport=this.realViewport,this.lastBoundFramebuffer==this.framebuffer&&t.bindFramebuffer(t.FRAMEBUFFER,null),this.isPatched=!1,setTimeout((function(){P(e)}),1)}},V.prototype.setTextureBounds=function(t,e){t||(t=[0,0,.5,1]),e||(e=[.5,0,.5,1]),this.viewportOffsetScale[0]=t[0],this.viewportOffsetScale[1]=t[1],this.viewportOffsetScale[2]=t[2],this.viewportOffsetScale[3]=t[3],this.viewportOffsetScale[4]=e[0],this.viewportOffsetScale[5]=e[1],this.viewportOffsetScale[6]=e[2],this.viewportOffsetScale[7]=e[3]},V.prototype.submitFrame=function(){var t=this.gl,e=this,n=[];if(this.dirtySubmitFrameBindings||n.push(t.CURRENT_PROGRAM,t.ARRAY_BUFFER_BINDING,t.ELEMENT_ARRAY_BUFFER_BINDING,t.TEXTURE_BINDING_2D,t.TEXTURE0),U(t,n,(function(t){e.realBindFramebuffer.call(t,t.FRAMEBUFFER,null);var n=0,i=0;e.instanceExt&&(n=t.getVertexAttrib(e.attribs.position,e.instanceExt.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE),i=t.getVertexAttrib(e.attribs.texCoord,e.instanceExt.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)),e.cullFace&&e.realDisable.call(t,t.CULL_FACE),e.depthTest&&e.realDisable.call(t,t.DEPTH_TEST),e.blend&&e.realDisable.call(t,t.BLEND),e.scissorTest&&e.realDisable.call(t,t.SCISSOR_TEST),e.stencilTest&&e.realDisable.call(t,t.STENCIL_TEST),e.realColorMask.call(t,!0,!0,!0,!0),e.realViewport.call(t,0,0,t.drawingBufferWidth,t.drawingBufferHeight),(e.ctxAttribs.alpha||u())&&(e.realClearColor.call(t,0,0,0,1),t.clear(t.COLOR_BUFFER_BIT)),t.useProgram(e.program),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,e.indexBuffer),t.bindBuffer(t.ARRAY_BUFFER,e.vertexBuffer),t.enableVertexAttribArray(e.attribs.position),t.enableVertexAttribArray(e.attribs.texCoord),t.vertexAttribPointer(e.attribs.position,2,t.FLOAT,!1,20,0),t.vertexAttribPointer(e.attribs.texCoord,3,t.FLOAT,!1,20,8),e.instanceExt&&(0!=n&&e.instanceExt.vertexAttribDivisorANGLE(e.attribs.position,0),0!=i&&e.instanceExt.vertexAttribDivisorANGLE(e.attribs.texCoord,0)),t.activeTexture(t.TEXTURE0),t.uniform1i(e.uniforms.diffuse,0),t.bindTexture(t.TEXTURE_2D,e.renderTarget),t.uniform4fv(e.uniforms.viewportOffsetScale,e.viewportOffsetScale),t.drawElements(t.TRIANGLES,e.indexCount,t.UNSIGNED_SHORT,0),e.cardboardUI&&e.cardboardUI.renderNoState(),e.realBindFramebuffer.call(e.gl,t.FRAMEBUFFER,e.framebuffer),e.ctxAttribs.preserveDrawingBuffer||(e.realClearColor.call(t,0,0,0,0),t.clear(t.COLOR_BUFFER_BIT)),e.dirtySubmitFrameBindings||e.realBindFramebuffer.call(t,t.FRAMEBUFFER,e.lastBoundFramebuffer),e.cullFace&&e.realEnable.call(t,t.CULL_FACE),e.depthTest&&e.realEnable.call(t,t.DEPTH_TEST),e.blend&&e.realEnable.call(t,t.BLEND),e.scissorTest&&e.realEnable.call(t,t.SCISSOR_TEST),e.stencilTest&&e.realEnable.call(t,t.STENCIL_TEST),e.realColorMask.apply(t,e.colorMask),e.realViewport.apply(t,e.viewport),!e.ctxAttribs.alpha&&e.ctxAttribs.preserveDrawingBuffer||e.realClearColor.apply(t,e.clearColor),e.instanceExt&&(0!=n&&e.instanceExt.vertexAttribDivisorANGLE(e.attribs.position,n),0!=i&&e.instanceExt.vertexAttribDivisorANGLE(e.attribs.texCoord,i))})),u()){var i=t.canvas;i.width==e.bufferWidth&&i.height==e.bufferHeight||(e.bufferWidth=i.width,e.bufferHeight=i.height,e.onResize())}},V.prototype.updateDeviceInfo=function(t){var e=this.gl,n=this,i=[e.ARRAY_BUFFER_BINDING,e.ELEMENT_ARRAY_BUFFER_BINDING];U(e,i,(function(e){var i=n.computeMeshVertices_(n.meshWidth,n.meshHeight,t);if(e.bindBuffer(e.ARRAY_BUFFER,n.vertexBuffer),e.bufferData(e.ARRAY_BUFFER,i,e.STATIC_DRAW),!n.indexCount){var r=n.computeMeshIndices_(n.meshWidth,n.meshHeight);e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,n.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,r,e.STATIC_DRAW),n.indexCount=r.length}}))},V.prototype.computeMeshVertices_=function(t,e,n){for(var i=new Float32Array(2*t*e*5),r=n.getLeftEyeVisibleTanAngles(),o=n.getLeftEyeNoLensTanAngles(),s=n.getLeftEyeVisibleScreenRect(o),a=0,l=0;l<2;l++){for(var c=0;c<e;c++)for(var u=0;u<t;u++,a++){var d=u/(t-1),p=c/(e-1),f=d,m=p,g=h(r[0],r[2],d),v=h(r[3],r[1],p),y=Math.sqrt(g*g+v*v),A=n.distortion.distortInverse(y),x=v*A/y;d=(g*A/y-o[0])/(o[2]-o[0]),p=(x-o[3])/(o[1]-o[3]),d=2*(s.x+d*s.width-.5),p=2*(s.y+p*s.height-.5),i[5*a+0]=d,i[5*a+1]=p,i[5*a+2]=f,i[5*a+3]=m,i[5*a+4]=l}var _=r[2]-r[0];r[0]=-(_+r[0]),r[2]=_-r[2],_=o[2]-o[0],o[0]=-(_+o[0]),o[2]=_-o[2],s.x=1-(s.x+s.width)}return i},V.prototype.computeMeshIndices_=function(t,e){for(var n=new Uint16Array(2*(t-1)*(e-1)*6),i=t/2,r=e/2,o=0,s=0,a=0;a<2;a++)for(var l=0;l<e;l++)for(var c=0;c<t;c++,o++)0!=c&&0!=l&&(c<=i==l<=r?(n[s++]=o,n[s++]=o-t-1,n[s++]=o-t,n[s++]=o-t-1,n[s++]=o,n[s++]=o-1):(n[s++]=o-1,n[s++]=o-t,n[s++]=o,n[s++]=o-t,n[s++]=o-1,n[s++]=o-t-1));return n},V.prototype.getOwnPropertyDescriptor_=function(t,e){var n=Object.getOwnPropertyDescriptor(t,e);return void 0!==n.get&&void 0!==n.set||(n.configurable=!0,n.enumerable=!0,n.get=function(){return this.getAttribute(e)},n.set=function(t){this.setAttribute(e,t)}),n};var k=["attribute vec2 position;","uniform mat4 projectionMat;","void main() {"," gl_Position = projectionMat * vec4( position, -1.0, 1.0 );","}"].join("\n"),W=["precision mediump float;","uniform vec4 color;","void main() {"," gl_FragColor = color;","}"].join("\n"),j=Math.PI/180,X=60,q=12,Y=20,Q=1,Z=.75,J=.3125,K=4,$=28,tt=1.5;function et(t){this.gl=t,this.attribs={position:0},this.program=S(t,k,W,this.attribs),this.uniforms=T(t,this.program),this.vertexBuffer=t.createBuffer(),this.gearOffset=0,this.gearVertexCount=0,this.arrowOffset=0,this.arrowVertexCount=0,this.projMat=new Float32Array(16),this.listener=null,this.onResize()}function nt(t){this.coefficients=t}et.prototype.destroy=function(){var t=this.gl;this.listener&&t.canvas.removeEventListener("click",this.listener,!1),t.deleteProgram(this.program),t.deleteBuffer(this.vertexBuffer)},et.prototype.listen=function(t,e){var n=this.gl.canvas;this.listener=function(i){var r=n.clientWidth/2,o=$*tt;i.clientX>r-o&&i.clientX<r+o&&i.clientY>n.clientHeight-o?t(i):i.clientX<o&&i.clientY<o&&e(i)},n.addEventListener("click",this.listener,!1)},et.prototype.onResize=function(){var t=this.gl,e=this,n=[t.ARRAY_BUFFER_BINDING];U(t,n,(function(t){var n=[],i=t.drawingBufferWidth/2,r=Math.max(screen.width,screen.height)*window.devicePixelRatio,o=t.drawingBufferWidth/r*window.devicePixelRatio,s=K*o/2,a=$*tt*o,l=$*o/2,c=($*tt-$)*o;function h(t,e){var r=(90-t)*j,o=Math.cos(r),s=Math.sin(r);n.push(J*o*l+i,J*s*l+l),n.push(e*o*l+i,e*s*l+l)}n.push(i-s,a),n.push(i-s,t.drawingBufferHeight),n.push(i+s,a),n.push(i+s,t.drawingBufferHeight),e.gearOffset=n.length/2;for(var u=0;u<=6;u++){var d=u*X;h(d,Q),h(d+q,Q),h(d+Y,Z),h(d+(X-Y),Z),h(d+(X-q),Q)}function p(e,i){n.push(c+e,t.drawingBufferHeight-c-i)}e.gearVertexCount=n.length/2-e.gearOffset,e.arrowOffset=n.length/2;var f=s/Math.sin(45*j);p(0,l),p(l,0),p(l+f,f),p(f,l+f),p(f,l-f),p(0,l),p(l,2*l),p(l+f,2*l-f),p(f,l-f),p(0,l),p(f,l-s),p($*o,l-s),p(f,l+s),p($*o,l+s),e.arrowVertexCount=n.length/2-e.arrowOffset,t.bindBuffer(t.ARRAY_BUFFER,e.vertexBuffer),t.bufferData(t.ARRAY_BUFFER,new Float32Array(n),t.STATIC_DRAW)}))},et.prototype.render=function(){var t=this.gl,e=this,n=[t.CULL_FACE,t.DEPTH_TEST,t.BLEND,t.SCISSOR_TEST,t.STENCIL_TEST,t.COLOR_WRITEMASK,t.VIEWPORT,t.CURRENT_PROGRAM,t.ARRAY_BUFFER_BINDING];U(t,n,(function(t){t.disable(t.CULL_FACE),t.disable(t.DEPTH_TEST),t.disable(t.BLEND),t.disable(t.SCISSOR_TEST),t.disable(t.STENCIL_TEST),t.colorMask(!0,!0,!0,!0),t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight),e.renderNoState()}))},et.prototype.renderNoState=function(){var t=this.gl;t.useProgram(this.program),t.bindBuffer(t.ARRAY_BUFFER,this.vertexBuffer),t.enableVertexAttribArray(this.attribs.position),t.vertexAttribPointer(this.attribs.position,2,t.FLOAT,!1,8,0),t.uniform4f(this.uniforms.color,1,1,1,1),L(this.projMat,0,t.drawingBufferWidth,0,t.drawingBufferHeight,.1,1024),t.uniformMatrix4fv(this.uniforms.projectionMat,!1,this.projMat),t.drawArrays(t.TRIANGLE_STRIP,0,4),t.drawArrays(t.TRIANGLE_STRIP,this.gearOffset,this.gearVertexCount),t.drawArrays(t.TRIANGLE_STRIP,this.arrowOffset,this.arrowVertexCount)},nt.prototype.distortInverse=function(t){for(var e=0,n=1,i=t-this.distort(e);Math.abs(n-e)>1e-4;){var r=t-this.distort(n),o=n-r*((n-e)/(r-i));e=n,n=o,i=r}return n},nt.prototype.distort=function(t){for(var e=t*t,n=0,i=0;i<this.coefficients.length;i++)n=e*(n+this.coefficients[i]);return(n+1)*t};var it=Math.PI/180,rt=180/Math.PI,ot=function(t,e,n){this.x=t||0,this.y=e||0,this.z=n||0};ot.prototype={constructor:ot,set:function(t,e,n){return this.x=t,this.y=e,this.z=n,this},copy:function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},normalize:function(){var t=this.length();if(0!==t){var e=1/t;this.multiplyScalar(e)}else this.x=0,this.y=0,this.z=0;return this},multiplyScalar:function(t){this.x*=t,this.y*=t,this.z*=t},applyQuaternion:function(t){var e=this.x,n=this.y,i=this.z,r=t.x,o=t.y,s=t.z,a=t.w,l=a*e+o*i-s*n,c=a*n+s*e-r*i,h=a*i+r*n-o*e,u=-r*e-o*n-s*i;return this.x=l*a+u*-r+c*-s-h*-o,this.y=c*a+u*-o+h*-r-l*-s,this.z=h*a+u*-s+l*-o-c*-r,this},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z},crossVectors:function(t,e){var n=t.x,i=t.y,r=t.z,o=e.x,s=e.y,a=e.z;return this.x=i*a-r*s,this.y=r*o-n*a,this.z=n*s-i*o,this}};var st,at,lt,ct=function(t,e,n,i){this.x=t||0,this.y=e||0,this.z=n||0,this.w=void 0!==i?i:1};function ht(t){this.width=t.width||_(),this.height=t.height||w(),this.widthMeters=t.widthMeters,this.heightMeters=t.heightMeters,this.bevelMeters=t.bevelMeters}ct.prototype={constructor:ct,set:function(t,e,n,i){return this.x=t,this.y=e,this.z=n,this.w=i,this},copy:function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=t.w,this},setFromEulerXYZ:function(t,e,n){var i=Math.cos(t/2),r=Math.cos(e/2),o=Math.cos(n/2),s=Math.sin(t/2),a=Math.sin(e/2),l=Math.sin(n/2);return this.x=s*r*o+i*a*l,this.y=i*a*o-s*r*l,this.z=i*r*l+s*a*o,this.w=i*r*o-s*a*l,this},setFromEulerYXZ:function(t,e,n){var i=Math.cos(t/2),r=Math.cos(e/2),o=Math.cos(n/2),s=Math.sin(t/2),a=Math.sin(e/2),l=Math.sin(n/2);return this.x=s*r*o+i*a*l,this.y=i*a*o-s*r*l,this.z=i*r*l-s*a*o,this.w=i*r*o+s*a*l,this},setFromAxisAngle:function(t,e){var n=e/2,i=Math.sin(n);return this.x=t.x*i,this.y=t.y*i,this.z=t.z*i,this.w=Math.cos(n),this},multiply:function(t){return this.multiplyQuaternions(this,t)},multiplyQuaternions:function(t,e){var n=t.x,i=t.y,r=t.z,o=t.w,s=e.x,a=e.y,l=e.z,c=e.w;return this.x=n*c+o*s+i*l-r*a,this.y=i*c+o*a+r*s-n*l,this.z=r*c+o*l+n*a-i*s,this.w=o*c-n*s-i*a-r*l,this},inverse:function(){return this.x*=-1,this.y*=-1,this.z*=-1,this.normalize(),this},normalize:function(){var t=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);return 0===t?(this.x=0,this.y=0,this.z=0,this.w=1):(t=1/t,this.x=this.x*t,this.y=this.y*t,this.z=this.z*t,this.w=this.w*t),this},slerp:function(t,e){if(0===e)return this;if(1===e)return this.copy(t);var n=this.x,i=this.y,r=this.z,o=this.w,s=o*t.w+n*t.x+i*t.y+r*t.z;if(s<0?(this.w=-t.w,this.x=-t.x,this.y=-t.y,this.z=-t.z,s=-s):this.copy(t),s>=1)return this.w=o,this.x=n,this.y=i,this.z=r,this;var a=Math.acos(s),l=Math.sqrt(1-s*s);if(Math.abs(l)<.001)return this.w=.5*(o+this.w),this.x=.5*(n+this.x),this.y=.5*(i+this.y),this.z=.5*(r+this.z),this;var c=Math.sin((1-e)*a)/l,h=Math.sin(e*a)/l;return this.w=o*c+this.w*h,this.x=n*c+this.x*h,this.y=i*c+this.y*h,this.z=r*c+this.z*h,this},setFromUnitVectors:(lt=1e-6,function(t,e){return void 0===st&&(st=new ot),(at=t.dot(e)+1)<lt?(at=0,Math.abs(t.x)>Math.abs(t.z)?st.set(-t.y,t.x,0):st.set(0,-t.z,t.y)):st.crossVectors(t,e),this.x=st.x,this.y=st.y,this.z=st.z,this.w=at,this.normalize(),this})};var ut=new ht({widthMeters:.11,heightMeters:.062,bevelMeters:.004}),dt=new ht({widthMeters:.1038,heightMeters:.0584,bevelMeters:.004}),pt={CardboardV1:new mt({id:"CardboardV1",label:"Cardboard I/O 2014",fov:40,interLensDistance:.06,baselineLensDistance:.035,screenLensDistance:.042,distortionCoefficients:[.441,.156],inverseCoefficients:[-.4410035,.42756155,-.4804439,.5460139,-.58821183,.5733938,-.48303202,.33299083,-.17573841,.0651772,-.01488963,.001559834]}),CardboardV2:new mt({id:"CardboardV2",label:"Cardboard I/O 2015",fov:60,interLensDistance:.064,baselineLensDistance:.035,screenLensDistance:.039,distortionCoefficients:[.34,.55],inverseCoefficients:[-.33836704,-.18162185,.862655,-1.2462051,1.0560602,-.58208317,.21609078,-.05444823,.009177956,-.0009904169,6183535e-11,-16981803e-13]})};function ft(t,e){this.viewer=pt.CardboardV2,this.updateDeviceParams(t),this.distortion=new nt(this.viewer.distortionCoefficients);for(var n=0;n<e.length;n++){var i=e[n];pt[i.id]=new mt(i)}}function mt(t){this.id=t.id,this.label=t.label,this.fov=t.fov,this.interLensDistance=t.interLensDistance,this.baselineLensDistance=t.baselineLensDistance,this.screenLensDistance=t.screenLensDistance,this.distortionCoefficients=t.distortionCoefficients,this.inverseCoefficients=t.inverseCoefficients}ft.prototype.updateDeviceParams=function(t){this.device=this.determineDevice_(t)||this.device},ft.prototype.getDevice=function(){return this.device},ft.prototype.setViewer=function(t){this.viewer=t,this.distortion=new nt(this.viewer.distortionCoefficients)},ft.prototype.determineDevice_=function(t){if(!t)return u()?(console.warn("Using fallback iOS device measurements."),dt):(console.warn("Using fallback Android device measurements."),ut);var e=.0254,n=e/t.xdpi,i=e/t.ydpi;return new ht({widthMeters:n*_(),heightMeters:i*w(),bevelMeters:.001*t.bevelMm})},ft.prototype.getDistortedFieldOfViewLeftEye=function(){var t=this.viewer,e=this.device,n=this.distortion,i=t.screenLensDistance,r=(e.widthMeters-t.interLensDistance)/2,o=t.interLensDistance/2,s=t.baselineLensDistance-e.bevelMeters,a=e.heightMeters-s,l=rt*Math.atan(n.distort(r/i)),c=rt*Math.atan(n.distort(o/i)),h=rt*Math.atan(n.distort(s/i)),u=rt*Math.atan(n.distort(a/i));return{leftDegrees:Math.min(l,t.fov),rightDegrees:Math.min(c,t.fov),downDegrees:Math.min(h,t.fov),upDegrees:Math.min(u,t.fov)}},ft.prototype.getLeftEyeVisibleTanAngles=function(){var t=this.viewer,e=this.device,n=this.distortion,i=Math.tan(-it*t.fov),r=Math.tan(it*t.fov),o=Math.tan(it*t.fov),s=Math.tan(-it*t.fov),a=e.widthMeters/4,l=e.heightMeters/2,c=t.baselineLensDistance-e.bevelMeters-l,h=t.interLensDistance/2-a,u=-c,d=t.screenLensDistance,p=n.distort((h-a)/d),f=n.distort((u+l)/d),m=n.distort((h+a)/d),g=n.distort((u-l)/d),v=new Float32Array(4);return v[0]=Math.max(i,p),v[1]=Math.min(r,f),v[2]=Math.min(o,m),v[3]=Math.max(s,g),v},ft.prototype.getLeftEyeNoLensTanAngles=function(){var t=this.viewer,e=this.device,n=this.distortion,i=new Float32Array(4),r=n.distortInverse(Math.tan(-it*t.fov)),o=n.distortInverse(Math.tan(it*t.fov)),s=n.distortInverse(Math.tan(it*t.fov)),a=n.distortInverse(Math.tan(-it*t.fov)),l=e.widthMeters/4,c=e.heightMeters/2,h=t.baselineLensDistance-e.bevelMeters-c,u=t.interLensDistance/2-l,d=-h,p=t.screenLensDistance,f=(u-l)/p,m=(d+c)/p,g=(u+l)/p,v=(d-c)/p;return i[0]=Math.max(r,f),i[1]=Math.min(o,m),i[2]=Math.min(s,g),i[3]=Math.max(a,v),i},ft.prototype.getLeftEyeVisibleScreenRect=function(t){var e=this.viewer,n=this.device,i=e.screenLensDistance,r=(n.widthMeters-e.interLensDistance)/2,o=e.baselineLensDistance-n.bevelMeters,s=(t[0]*i+r)/n.widthMeters,a=(t[1]*i+o)/n.heightMeters,l=(t[2]*i+r)/n.widthMeters,c=(t[3]*i+o)/n.heightMeters;return{x:s,y:c,width:l-s,height:a-c}},ft.prototype.getFieldOfViewLeftEye=function(t){return t?this.getUndistortedFieldOfViewLeftEye():this.getDistortedFieldOfViewLeftEye()},ft.prototype.getFieldOfViewRightEye=function(t){var e=this.getFieldOfViewLeftEye(t);return{leftDegrees:e.rightDegrees,rightDegrees:e.leftDegrees,upDegrees:e.upDegrees,downDegrees:e.downDegrees}},ft.prototype.getUndistortedFieldOfViewLeftEye=function(){var t=this.getUndistortedParams_();return{leftDegrees:rt*Math.atan(t.outerDist),rightDegrees:rt*Math.atan(t.innerDist),downDegrees:rt*Math.atan(t.bottomDist),upDegrees:rt*Math.atan(t.topDist)}},ft.prototype.getUndistortedViewportLeftEye=function(){var t=this.getUndistortedParams_(),e=this.viewer,n=this.device,i=e.screenLensDistance,r=n.widthMeters/i,o=n.heightMeters/i,s=n.width/r,a=n.height/o,l=Math.round((t.eyePosX-t.outerDist)*s),c=Math.round((t.eyePosY-t.bottomDist)*a);return{x:l,y:c,width:Math.round((t.eyePosX+t.innerDist)*s)-l,height:Math.round((t.eyePosY+t.topDist)*a)-c}},ft.prototype.getUndistortedParams_=function(){var t=this.viewer,e=this.device,n=this.distortion,i=t.screenLensDistance,r=t.interLensDistance/2/i,o=e.widthMeters/i,s=e.heightMeters/i,a=o/2-r,l=(t.baselineLensDistance-e.bevelMeters)/i,c=t.fov,h=n.distortInverse(Math.tan(it*c)),u=Math.min(a,h),d=Math.min(r,h),p=Math.min(l,h);return{outerDist:u,innerDist:d,topDist:Math.min(s-l,h),bottomDist:p,eyePosX:a,eyePosY:l}},ft.Viewers=pt;var gt={format:1,last_updated:"2019-11-09T17:36:14Z",devices:[{type:"android",rules:[{mdmh:"asus/*/Nexus 7/*"},{ua:"Nexus 7"}],dpi:[320.8,323],bw:3,ac:500},{type:"android",rules:[{mdmh:"asus/*/ASUS_X00PD/*"},{ua:"ASUS_X00PD"}],dpi:245,bw:3,ac:500},{type:"android",rules:[{mdmh:"asus/*/ASUS_X008D/*"},{ua:"ASUS_X008D"}],dpi:282,bw:3,ac:500},{type:"android",rules:[{mdmh:"asus/*/ASUS_Z00AD/*"},{ua:"ASUS_Z00AD"}],dpi:[403,404.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Google/*/Pixel 2 XL/*"},{ua:"Pixel 2 XL"}],dpi:537.9,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Google/*/Pixel 3 XL/*"},{ua:"Pixel 3 XL"}],dpi:[558.5,553.8],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Google/*/Pixel XL/*"},{ua:"Pixel XL"}],dpi:[537.9,533],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Google/*/Pixel 3/*"},{ua:"Pixel 3"}],dpi:442.4,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Google/*/Pixel 2/*"},{ua:"Pixel 2"}],dpi:441,bw:3,ac:500},{type:"android",rules:[{mdmh:"Google/*/Pixel/*"},{ua:"Pixel"}],dpi:[432.6,436.7],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"HTC/*/HTC6435LVW/*"},{ua:"HTC6435LVW"}],dpi:[449.7,443.3],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"HTC/*/HTC One XL/*"},{ua:"HTC One XL"}],dpi:[315.3,314.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"htc/*/Nexus 9/*"},{ua:"Nexus 9"}],dpi:289,bw:3,ac:500},{type:"android",rules:[{mdmh:"HTC/*/HTC One M9/*"},{ua:"HTC One M9"}],dpi:[442.5,443.3],bw:3,ac:500},{type:"android",rules:[{mdmh:"HTC/*/HTC One_M8/*"},{ua:"HTC One_M8"}],dpi:[449.7,447.4],bw:3,ac:500},{type:"android",rules:[{mdmh:"HTC/*/HTC One/*"},{ua:"HTC One"}],dpi:472.8,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Huawei/*/Nexus 6P/*"},{ua:"Nexus 6P"}],dpi:[515.1,518],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Huawei/*/BLN-L24/*"},{ua:"HONORBLN-L24"}],dpi:480,bw:4,ac:500},{type:"android",rules:[{mdmh:"Huawei/*/BKL-L09/*"},{ua:"BKL-L09"}],dpi:403,bw:3.47,ac:500},{type:"android",rules:[{mdmh:"LENOVO/*/Lenovo PB2-690Y/*"},{ua:"Lenovo PB2-690Y"}],dpi:[457.2,454.713],bw:3,ac:500},{type:"android",rules:[{mdmh:"LGE/*/Nexus 5X/*"},{ua:"Nexus 5X"}],dpi:[422,419.9],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"LGE/*/LGMS345/*"},{ua:"LGMS345"}],dpi:[221.7,219.1],bw:3,ac:500},{type:"android",rules:[{mdmh:"LGE/*/LG-D800/*"},{ua:"LG-D800"}],dpi:[422,424.1],bw:3,ac:500},{type:"android",rules:[{mdmh:"LGE/*/LG-D850/*"},{ua:"LG-D850"}],dpi:[537.9,541.9],bw:3,ac:500},{type:"android",rules:[{mdmh:"LGE/*/VS985 4G/*"},{ua:"VS985 4G"}],dpi:[537.9,535.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"LGE/*/Nexus 5/*"},{ua:"Nexus 5 B"}],dpi:[442.4,444.8],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"LGE/*/Nexus 4/*"},{ua:"Nexus 4"}],dpi:[319.8,318.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"LGE/*/LG-P769/*"},{ua:"LG-P769"}],dpi:[240.6,247.5],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"LGE/*/LGMS323/*"},{ua:"LGMS323"}],dpi:[206.6,204.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"LGE/*/LGLS996/*"},{ua:"LGLS996"}],dpi:[403.4,401.5],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Micromax/*/4560MMX/*"},{ua:"4560MMX"}],dpi:[240,219.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Micromax/*/A250/*"},{ua:"Micromax A250"}],dpi:[480,446.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"Micromax/*/Micromax AQ4501/*"},{ua:"Micromax AQ4501"}],dpi:240,bw:3,ac:500},{type:"android",rules:[{mdmh:"motorola/*/G5/*"},{ua:"Moto G (5) Plus"}],dpi:[403.4,403],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/DROID RAZR/*"},{ua:"DROID RAZR"}],dpi:[368.1,256.7],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/XT830C/*"},{ua:"XT830C"}],dpi:[254,255.9],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/XT1021/*"},{ua:"XT1021"}],dpi:[254,256.7],bw:3,ac:500},{type:"android",rules:[{mdmh:"motorola/*/XT1023/*"},{ua:"XT1023"}],dpi:[254,256.7],bw:3,ac:500},{type:"android",rules:[{mdmh:"motorola/*/XT1028/*"},{ua:"XT1028"}],dpi:[326.6,327.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/XT1034/*"},{ua:"XT1034"}],dpi:[326.6,328.4],bw:3,ac:500},{type:"android",rules:[{mdmh:"motorola/*/XT1053/*"},{ua:"XT1053"}],dpi:[315.3,316.1],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/XT1562/*"},{ua:"XT1562"}],dpi:[403.4,402.7],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/Nexus 6/*"},{ua:"Nexus 6 B"}],dpi:[494.3,489.7],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/XT1063/*"},{ua:"XT1063"}],dpi:[295,296.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/XT1064/*"},{ua:"XT1064"}],dpi:[295,295.6],bw:3,ac:500},{type:"android",rules:[{mdmh:"motorola/*/XT1092/*"},{ua:"XT1092"}],dpi:[422,424.1],bw:3,ac:500},{type:"android",rules:[{mdmh:"motorola/*/XT1095/*"},{ua:"XT1095"}],dpi:[422,423.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"motorola/*/G4/*"},{ua:"Moto G (4)"}],dpi:401,bw:4,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/A0001/*"},{ua:"A0001"}],dpi:[403.4,401],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE E1001/*"},{ua:"ONE E1001"}],dpi:[442.4,441.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE E1003/*"},{ua:"ONE E1003"}],dpi:[442.4,441.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE E1005/*"},{ua:"ONE E1005"}],dpi:[442.4,441.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE A2001/*"},{ua:"ONE A2001"}],dpi:[391.9,405.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE A2003/*"},{ua:"ONE A2003"}],dpi:[391.9,405.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE A2005/*"},{ua:"ONE A2005"}],dpi:[391.9,405.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A3000/*"},{ua:"ONEPLUS A3000"}],dpi:401,bw:3,ac:500},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A3003/*"},{ua:"ONEPLUS A3003"}],dpi:401,bw:3,ac:500},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A3010/*"},{ua:"ONEPLUS A3010"}],dpi:401,bw:3,ac:500},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A5000/*"},{ua:"ONEPLUS A5000 "}],dpi:[403.411,399.737],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONE A5010/*"},{ua:"ONEPLUS A5010"}],dpi:[403,400],bw:2,ac:1e3},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A6000/*"},{ua:"ONEPLUS A6000"}],dpi:401,bw:3,ac:500},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A6003/*"},{ua:"ONEPLUS A6003"}],dpi:401,bw:3,ac:500},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A6010/*"},{ua:"ONEPLUS A6010"}],dpi:401,bw:2,ac:500},{type:"android",rules:[{mdmh:"OnePlus/*/ONEPLUS A6013/*"},{ua:"ONEPLUS A6013"}],dpi:401,bw:2,ac:500},{type:"android",rules:[{mdmh:"OPPO/*/X909/*"},{ua:"X909"}],dpi:[442.4,444.1],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-I9082/*"},{ua:"GT-I9082"}],dpi:[184.7,185.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G360P/*"},{ua:"SM-G360P"}],dpi:[196.7,205.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/Nexus S/*"},{ua:"Nexus S"}],dpi:[234.5,229.8],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-I9300/*"},{ua:"GT-I9300"}],dpi:[304.8,303.9],bw:5,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-T230NU/*"},{ua:"SM-T230NU"}],dpi:216,bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SGH-T399/*"},{ua:"SGH-T399"}],dpi:[217.7,231.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SGH-M919/*"},{ua:"SGH-M919"}],dpi:[440.8,437.7],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-N9005/*"},{ua:"SM-N9005"}],dpi:[386.4,387],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SAMSUNG-SM-N900A/*"},{ua:"SAMSUNG-SM-N900A"}],dpi:[386.4,387.7],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-I9500/*"},{ua:"GT-I9500"}],dpi:[442.5,443.3],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/GT-I9505/*"},{ua:"GT-I9505"}],dpi:439.4,bw:4,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G900F/*"},{ua:"SM-G900F"}],dpi:[415.6,431.6],bw:5,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G900M/*"},{ua:"SM-G900M"}],dpi:[415.6,431.6],bw:5,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G800F/*"},{ua:"SM-G800F"}],dpi:326.8,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G906S/*"},{ua:"SM-G906S"}],dpi:[562.7,572.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-I9300/*"},{ua:"GT-I9300"}],dpi:[306.7,304.8],bw:5,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-T535/*"},{ua:"SM-T535"}],dpi:[142.6,136.4],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-N920C/*"},{ua:"SM-N920C"}],dpi:[515.1,518.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-N920P/*"},{ua:"SM-N920P"}],dpi:[386.3655,390.144],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-N920W8/*"},{ua:"SM-N920W8"}],dpi:[515.1,518.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-I9300I/*"},{ua:"GT-I9300I"}],dpi:[304.8,305.8],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-I9195/*"},{ua:"GT-I9195"}],dpi:[249.4,256.7],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SPH-L520/*"},{ua:"SPH-L520"}],dpi:[249.4,255.9],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SAMSUNG-SGH-I717/*"},{ua:"SAMSUNG-SGH-I717"}],dpi:285.8,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SPH-D710/*"},{ua:"SPH-D710"}],dpi:[217.7,204.2],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/GT-N7100/*"},{ua:"GT-N7100"}],dpi:265.1,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SCH-I605/*"},{ua:"SCH-I605"}],dpi:265.1,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/Galaxy Nexus/*"},{ua:"Galaxy Nexus"}],dpi:[315.3,314.2],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-N910H/*"},{ua:"SM-N910H"}],dpi:[515.1,518],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-N910C/*"},{ua:"SM-N910C"}],dpi:[515.2,520.2],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G130M/*"},{ua:"SM-G130M"}],dpi:[165.9,164.8],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G928I/*"},{ua:"SM-G928I"}],dpi:[515.1,518.4],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G920F/*"},{ua:"SM-G920F"}],dpi:580.6,bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G920P/*"},{ua:"SM-G920P"}],dpi:[522.5,577],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G925F/*"},{ua:"SM-G925F"}],dpi:580.6,bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G925V/*"},{ua:"SM-G925V"}],dpi:[522.5,576.6],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G930F/*"},{ua:"SM-G930F"}],dpi:576.6,bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G935F/*"},{ua:"SM-G935F"}],dpi:533,bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G950F/*"},{ua:"SM-G950F"}],dpi:[562.707,565.293],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G955U/*"},{ua:"SM-G955U"}],dpi:[522.514,525.762],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G955F/*"},{ua:"SM-G955F"}],dpi:[522.514,525.762],bw:3,ac:500},{type:"android",rules:[{mdmh:"samsung/*/SM-G960F/*"},{ua:"SM-G960F"}],dpi:[569.575,571.5],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G9600/*"},{ua:"SM-G9600"}],dpi:[569.575,571.5],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G960T/*"},{ua:"SM-G960T"}],dpi:[569.575,571.5],bw:3,ac:1e3},{type:"android",rules:[{mdmh:"samsung/*/SM-G960N/*"},{ua:"SM-G960N"}