@remotion/gif 4.0.177 → 4.0.178

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
 
2
- > @remotion/gif@4.0.176 build /Users/jonathanburger/remotion/packages/gif
2
+ > @remotion/gif@4.0.177 build /Users/jonathanburger/remotion/packages/gif
3
3
  > node build.mjs && bun --env-file=../.env.bundle bundle.ts
4
4
 
package/README.md CHANGED
@@ -1,58 +1,18 @@
1
- ### Remotion GIF
2
-
3
- [![NPM Version](https://img.shields.io/npm/v/@remotion/player.svg?style=flat)](https://www.npmjs.org/package/@remotion/player)
4
- [![NPM Downloads](https://img.shields.io/npm/dm/@remotion/player.svg?style=flat)](https://npmcharts.com/compare/@remotion/player?minimal=true)
5
- [![Install Size](https://packagephobia.now.sh/badge?p=@remotion/player)](https://packagephobia.now.sh/result?p=@remotion/player)
6
-
7
- The Remotion GIF package allows you to embed GIFs into a [Remotion](https://remotion.dev) composition that synchronizes with Remotion's `useCurrentFrame()`'s hook.
8
-
9
- To use this package, we'll be assuming [you already have a Remotion project](https://remotion.dev/docs).
10
-
11
- Use the same package manager to install this package that you have used to initialize your Remotion project:
12
-
13
- ```bash
14
- npm i @remotion/gif
15
- ```
16
-
17
- ```bash
18
- yarn add @remotion/gif
19
- ```
20
-
1
+ # @remotion/gif
2
+
3
+ Embed GIFs in a Remotion video
4
+
5
+ [![NPM Downloads](https://img.shields.io/npm/dm/@remotion/gif.svg?style=flat&color=black&label=Downloads)](https://npmcharts.com/compare/@remotion/gif?minimal=true)
6
+
7
+ ## Installation
8
+
21
9
  ```bash
22
- pnpm i @remotion/gif
23
- ```
24
-
25
- > Make sure all Remotion packages you install (`remotion`, `@remotion/player`, `@remotion/gif`...) [have the same version](https://remotion.dev/docs/version-mismatch).
26
-
27
- ### Basic Example
28
-
29
- This will render a GIF that fills the whole size of the composition:
30
-
31
- ```javascript
32
- import { useVideoConfig } from "remotion";
33
- import { Gif } from "@remotion/gif";
34
-  
35
- export const MyComponent = () => {
36
- const { width, height } = useVideoConfig();
37
-  
38
- return (
39
- <Gif
40
- src="https://media.giphy.com/media/3o72F7YT6s0EMFI0Za/giphy.gif"
41
- width={width}
42
- height={height}
43
- fit="fill"
44
- />
45
- );
46
- };
10
+ npm install @remotion/gif --save-exact
47
11
  ```
48
-
49
- ### API
50
-
51
- Prop | Function |
52
- --- | --- |
53
- src | is a required prop, and it is the source of the GIF. It can be a URL or a local image - [See how you can import assets](https://www.remotion.dev/docs/assets).|
54
- width | The display width of the GIF
55
- height | The display height of the GIF
56
- fill | The layout of the GIF in its current container. It accepts the following values: `fill`, `contain`, and `cover`
57
-
58
- For a complete reference of the available props, refer to [the @remotion/gif documentation](https://www.remotion.dev/docs/gif).
12
+
13
+ When installing a Remotion package, make sure to align the version of all `remotion` and `@remotion/*` packages to the same version.
14
+ Remove the `^` character from the version number to use the exact version.
15
+
16
+ ## Usage
17
+
18
+ See the [documentation](https://www.remotion.dev/docs/gif) for more information.
@@ -1,4 +1,8 @@
1
1
  import type { Frame, ParsedFrameWithoutPatch, ParsedGif } from './types';
2
2
  export declare const parseGIF: (arrayBuffer: ArrayBuffer) => ParsedGif;
3
- export declare const decompressFrame: (frame: Frame, gct: [number, number, number][]) => ParsedFrameWithoutPatch | null;
3
+ export declare const decompressFrame: (frame: Frame, gct: [
4
+ number,
5
+ number,
6
+ number
7
+ ][]) => ParsedFrameWithoutPatch | null;
4
8
  export declare const decompressFrames: (parsedGif: ParsedGif) => (ParsedFrameWithoutPatch | null)[];
@@ -4,4 +4,4 @@ exports.src = void 0;
4
4
  // Auto-generated by build.mjs
5
5
  exports.src =
6
6
  // eslint-disable-next-line no-template-curly-in-string
7
- '"use strict";(()=>{var P=(t,r,e={},n=e)=>{if(Array.isArray(r))r.forEach(o=>P(t,o,e,n));else if(typeof r=="function")r(t,e,n,P);else{let o=Object.keys(r)[0];Array.isArray(r[o])?(n[o]={},P(t,r[o],e,n[o])):n[o]=r[o](t,e,n,P)}return e},M=(t,r)=>function(e,n,o,c){let i=[],a=e.pos;for(;r(e,n,o);){let s={};if(c(e,t,n,s),e.pos===a)break;a=e.pos,i.push(s)}return i},g=(t,r)=>(e,n,o,c)=>{r(e,n,o)&&c(e,t,n,o)};var W=t=>({data:t,pos:0}),m=()=>t=>t.data[t.pos++],U=(t=0)=>r=>r.data[r.pos+t],f=t=>r=>r.data.subarray(r.pos,r.pos+=t),k=t=>r=>r.data.subarray(r.pos,r.pos+t),v=t=>r=>Array.from(f(t)(r)).map(e=>String.fromCharCode(e)).join(""),b=t=>r=>{let e=f(2)(r);return t?(e[1]<<8)+e[0]:(e[0]<<8)+e[1]},E=(t,r)=>(e,n,o)=>{let c=typeof r=="function"?r(e,n,o):r,i=f(t),a=new Array(c);for(let s=0;s<c;s++)a[s]=i(e);return a},$=(t,r,e)=>{let n=0;for(let o=0;o<e;o++)n+=Number(t[r+o]&&2**(e-o-1));return n},I=t=>r=>{let e=m()(r),n=new Array(8);for(let o=0;o<8;o++)n[7-o]=!!(e&1<<o);return Object.keys(t).reduce((o,c)=>{let i=t[c];return i.length?o[c]=$(n,i.index,i.length):o[c]=n[i.index],o},{})};var z={blocks:t=>{let e=[],n=t.data.length,o=0;for(let a=m()(t);a!==0&&a;a=m()(t)){if(t.pos+a>=n){let s=n-t.pos;e.push(f(s)(t)),o+=s;break}e.push(f(a)(t)),o+=a}let c=new Uint8Array(o),i=0;for(let a=0;a<e.length;a++)c.set(e[a],i),i+=e[a].length;return c}},q=g({gce:[{codes:f(2)},{byteSize:m()},{extras:I({future:{index:0,length:3},disposal:{index:3,length:3},userInput:{index:6},transparentColorGiven:{index:7}})},{delay:b(!0)},{transparentColorIndex:m()},{terminator:m()}]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===249}),H=g({image:[{code:m()},{descriptor:[{left:b(!0)},{top:b(!0)},{width:b(!0)},{height:b(!0)},{lct:I({exists:{index:0},interlaced:{index:1},sort:{index:2},future:{index:3,length:2},size:{index:5,length:3}})}]},g({lct:E(3,(t,r,e)=>2**(e.descriptor.lct.size+1))},(t,r,e)=>e.descriptor.lct.exists),{data:[{minCodeSize:m()},z]}]},t=>U()(t)===44),J=g({text:[{codes:f(2)},{blockSize:m()},{preData:(t,r,e)=>f(e.text.blockSize)(t)},z]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===1}),Q=g({application:[{codes:f(2)},{blockSize:m()},{id:(t,r,e)=>v(e.blockSize)(t)},z]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===255}),V=g({comment:[{codes:f(2)},z]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===254}),K=[{header:[{signature:v(3)},{version:v(3)}]},{lsd:[{width:b(!0)},{height:b(!0)},{gct:I({exists:{index:0},resolution:{index:1,length:3},sort:{index:4},size:{index:5,length:3}})},{backgroundColorIndex:m()},{pixelAspectRatio:m()}]},g({gct:E(3,(t,r)=>2**(r.lsd.gct.size+1))},(t,r)=>r.lsd.gct.exists),{frames:M([q,Q,V,H,J],t=>{let r=U()(t);return r===33||r===44})}];var X=(t,r)=>{let e=new Array(t.length),n=t.length/r,o=function(s,l){let u=t.slice(l*r,(l+1)*r);e.splice(...[s*r,r].concat(u))},c=[0,4,2,1],i=[8,8,4,2],a=0;for(let s=0;s<4;s++)for(let l=c[s];l<n;l+=i[s])o(l,a),a++;return e};var Z=(t,r,e)=>{let c=e,i,a,s,l,u;var w;let d,p;var C,y,h,_,G;let x=new Array(e),B=new Array(4096),T=new Array(4096),F=new Array(4096+1),R=t,S=1<<R,O=S+1;for(i=S+2,u=-1,s=R+1,a=(1<<s)-1,d=0;d<S;d++)B[d]=0,T[d]=d;var C,w,y,h,G,_;for(C=w=y=h=G=_=0,p=0;p<c;){if(h===0){if(w<s){C+=r[_]<<w,w+=8,_++;continue}if(d=C&a,C>>=s,w-=s,d>i||d===O)break;if(d===S){s=R+1,a=(1<<s)-1,i=S+2,u=-1;continue}if(u===-1){F[h++]=T[d],u=d,y=d;continue}for(l=d,d===i&&(F[h++]=y,d=u);d>S;)F[h++]=T[d],d=B[d];y=T[d]&255,F[h++]=y,i<4096&&(B[i]=u,T[i]=y,i++,!(i&a)&&i<4096&&(s++,a+=i)),u=l}h--,x[G++]=F[h],p++}for(p=G;p<c;p++)x[p]=0;return x};var j=t=>{let r=new Uint8Array(t);return P(W(r),K)},D=(t,r)=>{var i,a,s,l;if(!t.image)return console.warn("gif frame does not have associated image."),null;let{image:e}=t,n=e.descriptor.width*e.descriptor.height,o=Z(e.data.minCodeSize,e.data.blocks,n);return(i=e.descriptor.lct)!=null&&i.interlaced&&(o=X(o,e.descriptor.width)),{pixels:o,dims:{top:t.image.descriptor.top,left:t.image.descriptor.left,width:t.image.descriptor.width,height:t.image.descriptor.height},colorTable:(a=e.descriptor.lct)!=null&&a.exists?e.lct:r,delay:((l=(s=t.gce)==null?void 0:s.delay)!=null?l:10)*10,disposalType:t.gce?t.gce.extras.disposal:1,transparentIndex:t.gce&&t.gce.extras.transparentColorGiven?t.gce.transparentColorIndex:-1}};var L=t=>t.frames.filter(r=>"image"in r).map(r=>D(r,t.gct)).filter(Boolean).map(r=>r);var Y=t=>{let r=null;for(let e of t.frames)r=e.gce?e.gce:r,"image"in e&&!("gce"in e)&&r!==null&&(e.gce=r)},ee=({typedArray:t,dx:r,dy:e,width:n,height:o,gifWidth:c})=>{let i=e*c+r;for(let a=0;a<o;a++)for(let s=0;s<n;s++){let l=i+a*c+s;t[l*4]=0,t[l*4+1]=0,t[l*4+2]=0,t[l*4+3]=0}},te=(t,r,e)=>{let{width:n,height:o,top:c,left:i}=r.dims,a=c*e.width+i;for(let s=0;s<o;s++)for(let l=0;l<n;l++){let u=s*n+l,d=r.pixels[u];if(d!==r.transparentIndex){let p=a+s*e.width+l,x=r.colorTable[d];t[p*4]=x[0],t[p*4+1]=x[1],t[p*4+2]=x[2],t[p*4+3]=d===r.transparentIndex?0:255}}},N=(t,{signal:r})=>fetch(t,{signal:r}).then(e=>{var n;if(!((n=e.headers.get("Content-Type"))!=null&&n.includes("image/gif")))throw Error(`Wrong content type: "${e.headers.get("Content-Type")}"`);return e.arrayBuffer()}).then(e=>j(e)).then(e=>(Y(e),e)).then(e=>Promise.all([L(e),{width:e.lsd.width,height:e.lsd.height}])).then(([e,n])=>{let o=[],c=n.width*n.height*4,i=new Uint8ClampedArray(c);for(let a=0;a<e.length;++a){let s=e[a],l=e[a].disposalType===3?i.slice():null;if(te(i,s,n),o.push(i.slice()),e[a].disposalType===2)ee({typedArray:i,dx:s.dims.left,dy:s.dims.top,width:s.dims.width,height:s.dims.height,gifWidth:n.width});else if(e[a].disposalType===3){if(!l)throw Error("Disposal type 3 without previous frame");i=l}else i=o[a].slice()}return{...n,loaded:!0,delays:e.map(a=>a.delay),frames:o}});var A=new Map;self.addEventListener("message",t=>{let{type:r,src:e}=t.data||t;switch(r){case"parse":{if(!A.has(e)){let n=new AbortController,o={signal:n.signal};A.set(e,n),N(e,o).then(c=>{self.postMessage(Object.assign(c,{src:e}),c.frames.map(i=>i.buffer))}).catch(c=>{self.postMessage({src:e,error:c,loaded:!0})}).finally(()=>{A.delete(e)})}break}case"cancel":{A.has(e)&&(A.get(e).abort(),A.delete(e));break}default:break}});})();\n';
7
+ "\"use strict\";(()=>{var P=(t,r,e={},n=e)=>{if(Array.isArray(r))r.forEach(o=>P(t,o,e,n));else if(typeof r==\"function\")r(t,e,n,P);else{let o=Object.keys(r)[0];Array.isArray(r[o])?(n[o]={},P(t,r[o],e,n[o])):n[o]=r[o](t,e,n,P)}return e},M=(t,r)=>function(e,n,o,c){let i=[],a=e.pos;for(;r(e,n,o);){let s={};if(c(e,t,n,s),e.pos===a)break;a=e.pos,i.push(s)}return i},g=(t,r)=>(e,n,o,c)=>{r(e,n,o)&&c(e,t,n,o)};var W=t=>({data:t,pos:0}),m=()=>t=>t.data[t.pos++],U=(t=0)=>r=>r.data[r.pos+t],f=t=>r=>r.data.subarray(r.pos,r.pos+=t),k=t=>r=>r.data.subarray(r.pos,r.pos+t),v=t=>r=>Array.from(f(t)(r)).map(e=>String.fromCharCode(e)).join(\"\"),b=t=>r=>{let e=f(2)(r);return t?(e[1]<<8)+e[0]:(e[0]<<8)+e[1]},E=(t,r)=>(e,n,o)=>{let c=typeof r==\"function\"?r(e,n,o):r,i=f(t),a=new Array(c);for(let s=0;s<c;s++)a[s]=i(e);return a},$=(t,r,e)=>{let n=0;for(let o=0;o<e;o++)n+=Number(t[r+o]&&2**(e-o-1));return n},I=t=>r=>{let e=m()(r),n=new Array(8);for(let o=0;o<8;o++)n[7-o]=!!(e&1<<o);return Object.keys(t).reduce((o,c)=>{let i=t[c];return i.length?o[c]=$(n,i.index,i.length):o[c]=n[i.index],o},{})};var z={blocks:t=>{let e=[],n=t.data.length,o=0;for(let a=m()(t);a!==0&&a;a=m()(t)){if(t.pos+a>=n){let s=n-t.pos;e.push(f(s)(t)),o+=s;break}e.push(f(a)(t)),o+=a}let c=new Uint8Array(o),i=0;for(let a=0;a<e.length;a++)c.set(e[a],i),i+=e[a].length;return c}},q=g({gce:[{codes:f(2)},{byteSize:m()},{extras:I({future:{index:0,length:3},disposal:{index:3,length:3},userInput:{index:6},transparentColorGiven:{index:7}})},{delay:b(!0)},{transparentColorIndex:m()},{terminator:m()}]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===249}),H=g({image:[{code:m()},{descriptor:[{left:b(!0)},{top:b(!0)},{width:b(!0)},{height:b(!0)},{lct:I({exists:{index:0},interlaced:{index:1},sort:{index:2},future:{index:3,length:2},size:{index:5,length:3}})}]},g({lct:E(3,(t,r,e)=>2**(e.descriptor.lct.size+1))},(t,r,e)=>e.descriptor.lct.exists),{data:[{minCodeSize:m()},z]}]},t=>U()(t)===44),J=g({text:[{codes:f(2)},{blockSize:m()},{preData:(t,r,e)=>f(e.text.blockSize)(t)},z]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===1}),Q=g({application:[{codes:f(2)},{blockSize:m()},{id:(t,r,e)=>v(e.blockSize)(t)},z]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===255}),V=g({comment:[{codes:f(2)},z]},t=>{let r=k(2)(t);return r[0]===33&&r[1]===254}),K=[{header:[{signature:v(3)},{version:v(3)}]},{lsd:[{width:b(!0)},{height:b(!0)},{gct:I({exists:{index:0},resolution:{index:1,length:3},sort:{index:4},size:{index:5,length:3}})},{backgroundColorIndex:m()},{pixelAspectRatio:m()}]},g({gct:E(3,(t,r)=>2**(r.lsd.gct.size+1))},(t,r)=>r.lsd.gct.exists),{frames:M([q,Q,V,H,J],t=>{let r=U()(t);return r===33||r===44})}];var X=(t,r)=>{let e=new Array(t.length),n=t.length/r,o=function(s,l){let u=t.slice(l*r,(l+1)*r);e.splice(...[s*r,r].concat(u))},c=[0,4,2,1],i=[8,8,4,2],a=0;for(let s=0;s<4;s++)for(let l=c[s];l<n;l+=i[s])o(l,a),a++;return e};var Z=(t,r,e)=>{let c=e,i,a,s,l,u;var w;let d,p;var C,y,h,_,G;let x=new Array(e),B=new Array(4096),T=new Array(4096),F=new Array(4096+1),R=t,S=1<<R,O=S+1;for(i=S+2,u=-1,s=R+1,a=(1<<s)-1,d=0;d<S;d++)B[d]=0,T[d]=d;var C,w,y,h,G,_;for(C=w=y=h=G=_=0,p=0;p<c;){if(h===0){if(w<s){C+=r[_]<<w,w+=8,_++;continue}if(d=C&a,C>>=s,w-=s,d>i||d===O)break;if(d===S){s=R+1,a=(1<<s)-1,i=S+2,u=-1;continue}if(u===-1){F[h++]=T[d],u=d,y=d;continue}for(l=d,d===i&&(F[h++]=y,d=u);d>S;)F[h++]=T[d],d=B[d];y=T[d]&255,F[h++]=y,i<4096&&(B[i]=u,T[i]=y,i++,!(i&a)&&i<4096&&(s++,a+=i)),u=l}h--,x[G++]=F[h],p++}for(p=G;p<c;p++)x[p]=0;return x};var j=t=>{let r=new Uint8Array(t);return P(W(r),K)},D=(t,r)=>{var i,a,s,l;if(!t.image)return console.warn(\"gif frame does not have associated image.\"),null;let{image:e}=t,n=e.descriptor.width*e.descriptor.height,o=Z(e.data.minCodeSize,e.data.blocks,n);return(i=e.descriptor.lct)!=null&&i.interlaced&&(o=X(o,e.descriptor.width)),{pixels:o,dims:{top:t.image.descriptor.top,left:t.image.descriptor.left,width:t.image.descriptor.width,height:t.image.descriptor.height},colorTable:(a=e.descriptor.lct)!=null&&a.exists?e.lct:r,delay:((l=(s=t.gce)==null?void 0:s.delay)!=null?l:10)*10,disposalType:t.gce?t.gce.extras.disposal:1,transparentIndex:t.gce&&t.gce.extras.transparentColorGiven?t.gce.transparentColorIndex:-1}};var L=t=>t.frames.filter(r=>\"image\"in r).map(r=>D(r,t.gct)).filter(Boolean).map(r=>r);var Y=t=>{let r=null;for(let e of t.frames)r=e.gce?e.gce:r,\"image\"in e&&!(\"gce\"in e)&&r!==null&&(e.gce=r)},ee=({typedArray:t,dx:r,dy:e,width:n,height:o,gifWidth:c})=>{let i=e*c+r;for(let a=0;a<o;a++)for(let s=0;s<n;s++){let l=i+a*c+s;t[l*4]=0,t[l*4+1]=0,t[l*4+2]=0,t[l*4+3]=0}},te=(t,r,e)=>{let{width:n,height:o,top:c,left:i}=r.dims,a=c*e.width+i;for(let s=0;s<o;s++)for(let l=0;l<n;l++){let u=s*n+l,d=r.pixels[u];if(d!==r.transparentIndex){let p=a+s*e.width+l,x=r.colorTable[d];t[p*4]=x[0],t[p*4+1]=x[1],t[p*4+2]=x[2],t[p*4+3]=d===r.transparentIndex?0:255}}},N=(t,{signal:r})=>fetch(t,{signal:r}).then(e=>{var n;if(!((n=e.headers.get(\"Content-Type\"))!=null&&n.includes(\"image/gif\")))throw Error(`Wrong content type: \"${e.headers.get(\"Content-Type\")}\"`);return e.arrayBuffer()}).then(e=>j(e)).then(e=>(Y(e),e)).then(e=>Promise.all([L(e),{width:e.lsd.width,height:e.lsd.height}])).then(([e,n])=>{let o=[],c=n.width*n.height*4,i=new Uint8ClampedArray(c);for(let a=0;a<e.length;++a){let s=e[a],l=e[a].disposalType===3?i.slice():null;if(te(i,s,n),o.push(i.slice()),e[a].disposalType===2)ee({typedArray:i,dx:s.dims.left,dy:s.dims.top,width:s.dims.width,height:s.dims.height,gifWidth:n.width});else if(e[a].disposalType===3){if(!l)throw Error(\"Disposal type 3 without previous frame\");i=l}else i=o[a].slice()}return{...n,loaded:!0,delays:e.map(a=>a.delay),frames:o}});var A=new Map;self.addEventListener(\"message\",t=>{let{type:r,src:e}=t.data||t;switch(r){case\"parse\":{if(!A.has(e)){let n=new AbortController,o={signal:n.signal};A.set(e,n),N(e,o).then(c=>{self.postMessage(Object.assign(c,{src:e}),c.frames.map(i=>i.buffer))}).catch(c=>{self.postMessage({src:e,error:c,loaded:!0})}).finally(()=>{A.delete(e)})}break}case\"cancel\":{A.has(e)&&(A.get(e).abort(),A.delete(e));break}default:break}});})();\n";
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
- "name": "@remotion/gif",
3
- "version": "4.0.177",
4
- "description": "Gif component for remotion",
5
- "sideEffects": false,
6
2
  "repository": {
7
- "url": "https://github.com/remotion-dev/remotion"
3
+ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/gif"
8
4
  },
5
+ "name": "@remotion/gif",
6
+ "version": "4.0.178",
7
+ "description": "Embed GIFs in a Remotion video",
8
+ "sideEffects": false,
9
9
  "bugs": {
10
10
  "url": "https://github.com/remotion-dev/remotion/issues"
11
11
  },
@@ -24,17 +24,10 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "remotion": "4.0.177"
27
+ "remotion": "4.0.178"
28
28
  },
29
29
  "devDependencies": {
30
- "@jonny/eslint-config": "3.0.281",
31
- "@types/node": "18.14.6",
32
- "@types/react": "18.3.1",
33
- "@types/react-dom": "18.3.0",
34
30
  "esbuild": "0.18.6",
35
- "eslint": "8.56.0",
36
- "prettier": "3.2.5",
37
- "prettier-plugin-organize-imports": "3.2.4",
38
31
  "react": "18.3.1",
39
32
  "react-dom": "18.3.1",
40
33
  "webpack": "5.83.1"
@@ -53,6 +46,7 @@
53
46
  "publishConfig": {
54
47
  "access": "public"
55
48
  },
49
+ "homepage": "https://www.remotion.dev/docs/gif",
56
50
  "scripts": {
57
51
  "formatting": "prettier src --check",
58
52
  "lint": "eslint src --ext ts,tsx",