{
  "reviewedAt": "2026-10-23",
  "sourceKind": "Production editor working copy; not claimed to be a public GitHub commit",
  "excerpts": [
    {
      "file": "app/studio/filter-capabilities.ts",
      "start": 2,
      "end": 5,
      "code": "export const filterCapabilities={\n gaussian:{name:'Gaussian Blur',native:'gaussian blur'},unsharp:{name:'Unsharp Mask',native:'unsharp mask'},highpass:{name:'High Pass',native:'high pass'},box:{name:'Box Blur',native:'box blur'},motion:{name:'Motion Blur',native:'motion blur'},median:{name:'Median',native:'median'},minimum:{name:'Minimum',native:'minimum'},maximum:{name:'Maximum',native:'maximum'},mosaic:{name:'Mosaic',native:'mosaic'},noise:{name:'Add Noise',native:'add noise'},average:{name:'Average',native:'average'},blur:{name:'Blur',native:'blur'},blurMore:{name:'Blur More',native:'blur more'},sharpen:{name:'Sharpen',native:'sharpen'},sharpenEdges:{name:'Sharpen Edges',native:'sharpen edges'},sharpenMore:{name:'Sharpen More',native:'sharpen more'},findEdges:{name:'Find Edges',native:'find edges'},solarize:{name:'Solarize',native:'solarize'},\n twirl:{name:'Twirl',native:'twirl'},ripple:{name:'Ripple',native:null},shear:{name:'Shear',native:null},\n} as const;",
      "sha256": "9c8f3510206263d0cc919aff5e748a2ff83b33874b32fa04a16c14226ac02f21"
    },
    {
      "file": "app/studio/smart-filters.ts",
      "start": 9,
      "end": 9,
      "code": "export function validateSmartFilters(filters:SmartFilter[]){if(!Array.isArray(filters)||filters.length>16)throw Error('Use up to 16 Smart Filters.');const ids=new Set();for(const f of filters){if(!f||typeof f.id!=='string'||ids.has(f.id)||!Object.hasOwn(filterNames,f.type)||!Number.isFinite(f.radius)||f.radius<0||f.radius>50||!Number.isFinite(f.amount)||f.amount<0||f.amount>500||!Number.isFinite(f.threshold)||f.threshold<0||f.threshold>255||!Number.isFinite(f.opacity)||f.opacity<0||f.opacity>1||!Object.hasOwn(blendNames,f.blend)||typeof f.enabled!=='boolean')throw Error('Invalid Smart Filter.');if(f.angle!==undefined&&(!Number.isFinite(f.angle)||f.angle < -180||f.angle>180)||f.seed!==undefined&&(!Number.isInteger(f.seed)||f.seed<1||f.seed>2147483647)||f.distribution!==undefined&&!['uniform','gaussian'].includes(f.distribution)||f.monochromatic!==undefined&&typeof f.monochromatic!=='boolean')throw Error('Invalid Smart Filter options.');if(f.edge!==undefined&&!['wrap','clamp','transparent'].includes(f.edge)||f.type==='shear'&&(!Array.isArray(f.shear)||f.shear.length!==5||f.shear.some(n=>!Number.isFinite(n)||Math.abs(n)>100)))throw Error('Invalid geometric Smart Filter.');ids.add(f.id);}}",
      "sha256": "0bec5d06ef4db27e0e05f9b8ab81d44313958173f7d7c22695a431412770371d"
    },
    {
      "file": "app/studio/smart-filters.ts",
      "start": 12,
      "end": 12,
      "code": "export function nativeSmartFilters(filters:SmartFilter[],mask?:LayerMask){validateSmartFilters(filters);const unsupported=filters.find(f=>!filterCapabilities[f.type].native);if(unsupported)throw Error(filterNames[unsupported.type]+' Smart Filter is editable in Photoshot projects. Native PSD export for this operation is not supported yet; save a project or rasterize a duplicate.');return {enabled:true,validAtPosition:true,maskEnabled:!!mask?.enabled,maskLinked:mask?.linked!==false,maskExtendWithWhite:!mask,list:filters.map(f=>({type:filterCapabilities[f.type].native,name:filterNames[f.type],enabled:f.enabled,hasOptions:!simpleSmartTypes.includes(f.type as any),opacity:f.opacity,blendMode:f.blend.replaceAll('-',' '),foregroundColor:{r:0,g:0,b:0},backgroundColor:{r:255,g:255,b:255},filter:simpleSmartTypes.includes(f.type as any)?undefined:f.type==='twirl'?{angle:f.angle??0}:f.type==='motion'?{angle:f.angle??0,distance:{units:'Pixels',value:f.radius}}:f.type==='mosaic'?{cellSize:{units:'Pixels',value:Math.max(1,Math.round(f.radius))}}:f.type==='noise'?{amount:f.amount/100,distribution:f.distribution??'uniform',monochromatic:f.monochromatic??true,randomSeed:f.seed??1}:{radius:{units:'Pixels',value:f.radius},...(f.type==='unsharp'?{amount:f.amount/100,threshold:f.threshold}:{})}}))};}",
      "sha256": "0bec5d06ef4db27e0e05f9b8ab81d44313958173f7d7c22695a431412770371d"
    },
    {
      "file": "app/studio/psd-filter-cache.ts",
      "start": 13,
      "end": 14,
      "code": "export async function filterMaskGuard(cache:any){if(!cache?.extra)return undefined;const m=cache.extra,w=m.right-m.left,h=m.bottom-m.top;if(w<=0||h<=0||w*h>64*1024*1024||cache.depth!==8)return {unsupported:true};const pixels=decodePlane(m.data,m.compressionMode,w,h,true);return {bounds:[m.left,m.top,m.right,m.bottom],hash:Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new Uint8Array(pixels)))).map(n=>n.toString(16).padStart(2,'0')).join('')};}\nexport function editableNativeFilters(doc:StudioDoc,layer:Layer):Layer{if(layer.smartFilters!==undefined){validateSmartFilters(layer.smartFilters);return layer;}const native=unpackMetadata(layer.psdData??{}).placedLayer?.filter,cache=filterCache(doc,layer);if(!native?.list?.length)return layer;const names=Object.fromEntries(Object.entries(filterCapabilities).filter(([,c])=>c.native).map(([id,c])=>[c.native,id])) as Record<string,SmartFilter['type']>;if(native.list.some((f:any)=>!names[f.type]))throw Error('This stack contains filters that cannot yet be edited. Its original pixels and settings are preserved.');if(!cache||![8,16,32].includes(cache.depth)||cache.depth!==8&&!doc.precision)throw Error('This file has no supported unfiltered pixel cache. Open and save it in Photoshop before editing its Smart Filters.');const w=cache.right-cache.left,h=cache.bottom-cache.top;if(w<=0||h<=0||w*h>64*1024*1024)throw Error('The filter cache exceeds the supported size.');const filters:SmartFilter[]=native.list.map((f:any)=>({id:crypto.randomUUID(),type:names[f.type],radius:f.filter?.radius?.value??f.filter?.distance?.value??f.filter?.cellSize?.value??0,amount:['unsharp mask','add noise'].includes(f.type)?(f.filter.amount??0)*100:100,...(['motion blur','twirl'].includes(f.type)?{angle:f.filter.angle}:{}),...(f.type==='add noise'?{seed:Math.max(1,(f.filter.randomSeed??1)&2147483647),distribution:f.filter.distribution,monochromatic:f.filter.monochromatic}:{}),threshold:f.filter?.threshold??0,opacity:f.opacity??1,blend:(f.blendMode??'normal').replaceAll(' ','-'),enabled:native.enabled!==false&&f.enabled!==false}));validateSmartFilters(filters);let smartFilterMask:Layer['smartFilterMask'];if(cache.extra){const m=cache.extra,mw=m.right-m.left,mh=m.bottom-m.top;if(mw<=0||mh<=0||mw*mh>64*1024*1024)throw Error('Invalid filter mask size.');const a=cache.depth===8?decodePlane(m.data,m.compressionMode,mw,mh,true):Uint8Array.from(decodePrecisionPlane(m.data,m.compressionMode,mw,mh,cache.depth,true),v=>Math.round(Math.max(0,Math.min(1,v))*255)),mc=surface(mw,mh),mg=mc.getContext('2d')!,im=mg.createImageData(mw,mh);for(let p=0;p<a.length;p++){im.data[p*4]=im.data[p*4+1]=im.data[p*4+2]=a[p];im.data[p*4+3]=255;}mg.putImageData(im,0,0);const result=surface(layer.width,layer.height),rg=result.getContext('2d')!;rg.fillStyle=native.maskExtendWithWhite?'#fff':'#000';rg.fillRect(0,0,result.width,result.height);rg.drawImage(mc,m.left-layer.x,m.top-layer.y);const values=rg.getImageData(0,0,result.width,result.height).data;smartFilterMask={width:layer.width,height:layer.height,enabled:native.maskEnabled!==false,inverted:false,linked:native.maskLinked!==false,strokes:[],raster:{width:result.width,height:result.height,alpha:Array.from({length:result.width*result.height},(_,i)=>values[i*4])}};}if(doc.precision){let r=precisionLayerPixels({left:cache.left,top:cache.top,right:cache.right,bottom:cache.bottom,rawData:{large:true,channels:cache.channels.map((c:any,i:number)=>c?{id:i===25?-1:i,data:c.data,compression:c.compressionMode}:null).filter(Boolean)}},doc.precision.space,cache.depth as PrecisionDepth,profileBytes(doc.precision.profile));if(!r)throw Error('Missing native filter cache pixels.');if(w!==Math.round(layer.width)||h!==Math.round(layer.height)||cache.left!==layer.x||cache.top!==layer.y)r=resamplePrecision(r,Math.round(layer.width),Math.round(layer.height),(x,y)=>({x:x+layer.x-cache.left,y:y+layer.y-cache.top}));return {...layer,precision:packPrecision(r),precisionSource:precisionSource(layer.src),smartFilters:filters,smartFilterMask};}const c=surface(w,h),g=c.getContext('2d')!,data=g.createImageData(w,h);for(const [i,index]of [0,1,2,25].entries()){const ch=cache.channels[index];if(!ch&&index!==25)throw Error('The unfiltered cache is incomplete.');const plane=ch?(cache.depth===8?decodePlane(ch.data,ch.compressionMode,w,h,true):Uint8Array.from(decodePrecisionPlane(ch.data,ch.compressionMode,w,h,cache.depth,true),v=>Math.round(Math.max(0,Math.min(1,v))*255))):new Uint8Array(w*h).fill(255);for(let p=0;p<w*h;p++)data.data[p*4+i]=plane[p];}g.putImageData(data,0,0);const local=surface(layer.width,layer.height);local.getContext('2d')!.drawImage(c,cache.left-layer.x,cache.top-layer.y);const src=local.toDataURL();return {...layer,src,smartFilters:filters,smartFilterMask};}",
      "sha256": "dfda4350593358022573599a24c178c4e50c87c11c26def980d3c3dcedf99a90"
    }
  ],
  "productionUI": {
    "episode": 33,
    "at": "2026-10-24T00:46:30.831Z",
    "url": "https://slohero.com/photoshot/editor/",
    "inputKind": "AI-generated fictional adult demonstration PNG, not a real-person photograph",
    "selectionPartial": true,
    "stack": [
      {
        "type": "gaussian",
        "radius": 8,
        "amount": 100
      },
      {
        "type": "unsharp",
        "radius": 2,
        "amount": 120
      }
    ],
    "maskDensity": 0.75,
    "psdReopenStackExact": true,
    "psdReopenMaskExact": true,
    "passed": true,
    "errors": [],
    "imageRevision": "v3: restrained intermediate facial redesign from the original textual face descriptions; text-only generation."
  },
  "checks": [
    {
      "file": "smart-filter-mask-render-results.json",
      "sha256": "20ef1677c59dfef5e6eddb4539e77c7ab21bbd4888f5024e57676dd3c313fc1a",
      "results": {
        "passed": true,
        "checks": [
          "PSD/PSB native filter masks, source caches, private restoration and external mask edit detection",
          "Distinct instance masks, transformed masks, density/inversion and removed-stack cache cleanup",
          "Real Adobe-generated fixture: original pixels, selection mask and editable native Gaussian stack"
        ]
      },
      "freshRun": true
    },
    {
      "file": "smart-filter-expanded-results.json",
      "sha256": "37565848313e2d52f10ce60bb34171eca3ab8d2be4e47d014a4902a0943faf19",
      "results": {
        "passed": true,
        "checks": [
          "smart-expanded-average.psd",
          "smart-expanded-average.psb",
          "smart-expanded-blur.psd",
          "smart-expanded-blur.psb",
          "smart-expanded-blurMore.psd",
          "smart-expanded-blurMore.psb",
          "smart-expanded-sharpen.psd",
          "smart-expanded-sharpen.psb",
          "smart-expanded-sharpenEdges.psd",
          "smart-expanded-sharpenEdges.psb",
          "smart-expanded-sharpenMore.psd",
          "smart-expanded-sharpenMore.psb",
          "smart-expanded-findEdges.psd",
          "smart-expanded-findEdges.psb",
          "smart-expanded-solarize.psd",
          "smart-expanded-solarize.psb",
          "RGB32 native cache",
          "Gray8 native cache",
          "Gray16 native cache",
          "CMYK8 native cache",
          "CMYK16 native cache",
          "Lab16 native cache"
        ]
      },
      "freshRun": true
    },
    {
      "file": "smart-filter-mask-ui-results.json",
      "sha256": "134114e54112cfcf446b707820e4f3f11da884c5e5d94a1c56e7516d1338abc2",
      "results": {
        "passed": true,
        "nativePsdImport": true,
        "editNativeStack": true,
        "cancel": true,
        "maskInversionDensity": true,
        "undoRedo": true,
        "recovery": true,
        "errors": []
      },
      "freshRun": true
    }
  ],
  "imageDisclosure": "AI 생성 시연 이미지 · 실제 인물 촬영 및 공식 협업 이미지가 아닙니다. 편집 화면과 결과는 실제 포토샷에서 만들었습니다.",
  "imageRevision": {
    "version": 3,
    "at": "2026-10-24T00:46:30.831Z",
    "method": "Text-only intermediate variation with two local adjustments; no reference photographs provided to generator.",
    "sourceSha256": "3473eb946120206f6103ed99f7ed823ac8d3213c1c735aebf23f721efccf4ce0",
    "previousImagesRetained": true
  }
}