(()=>{"use strict";class Preconditions{static checkArgument(cond,msg,...args){if(!cond)throw new Error(msg==null?"invalid argument":Preconditions.format(msg,...args))}static checkState(cond,msg,...args){if(!cond)throw new Error(msg==null?"invalid state":Preconditions.format(msg,...args))}static checkEquals(a,b,msg,...args){if(a!==b)throw new Error(msg==null?Preconditions.format("{} != {}",Preconditions.stringify(a),Preconditions.stringify(b)):Preconditions.format(msg,...args))}static stringify(x){if(x==null||typeof x==="symbol")return String(x);else try{return JSON.stringify(x)}catch(e){return String(x)}}static checkExists(x,msg,...args){if(x==null)throw new Error(msg==null?"argument is null":Preconditions.format(msg,...args));return x}static format(template,...args){let i=0;return template.replace(/\{}/g,(()=>i{const maybeFullstop=opts.message.endsWith(".")?"":".";return`[${opts.code}]: ${opts.message}${maybeFullstop}`.trim()};class CanvaErrorClass extends Error{constructor(opts){opts.code=appSandboxErrorCodeMapper(opts.code);super(formattedErrorMessage(opts));this.code=opts.code;this.name="CanvaError";this.rawMessage=opts.message;Object.setPrototypeOf(this,CanvaErrorClass.prototype)}}function setAppSandboxErrorCodeMapper(mapper){appSandboxErrorCodeMapper=mapper}let appSandboxErrorCodeMapper=code=>code;class MessageBus{constructor(handler,port,errorService){this.handler=handler;this.port=port;this.errorService=errorService;this.send=message=>{try{this.port.postMessage(message);return Result.Ok()}catch(e){this.errorService.errorException(e);return Result.Err(e)}};this.onMessageError=e=>{this.errorService.errorException(e)};this.onMessage=({data})=>{if(!data){this.errorService.error(new CanvaErrorClass({code:"internal_error",message:`missing data in 'MessageEvent'`}));return}try{this.handler.receive(data)}catch(e){this.errorService.errorException(e)}};this.port.onmessage=this.onMessage;this.port.onmessageerror=this.onMessageError}}function uuidv4(rng){const randomValues=getRandomValues(rng,31);let currentRandomValue=0;return`${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g,(function(c){const cN=Number(c);return(cN^randomValues[currentRandomValue++]&15>>cN/4).toString(16)}))}const HEX_CHARS="0123456789abcdef";function uuidv7(){const bytes=Uint8Array.from(getRandomValues(undefined,16));const now=Date.now();bytes[0]=Math.trunc(now/1099511627776)&255;bytes[1]=Math.trunc(now/4294967296)&255;bytes[2]=Math.trunc(now/16777216)&255;bytes[3]=Math.trunc(now/65536)&255;bytes[4]=Math.trunc(now/256)&255;bytes[5]=now&255;bytes[6]=112|bytes[6]&15;bytes[8]=128|bytes[8]&63;let hex="";for(let i=0;i<16;i++)hex+=HEX_CHARS[bytes[i]>>>4]+HEX_CHARS[bytes[i]&15];return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`}function getRandomValues(rng,amount){if(!rng&&typeof window!=="undefined"&&typeof window.crypto!=="undefined"&&typeof window.crypto.getRandomValues==="function")return window.crypto.getRandomValues(new Uint8Array(amount));const random=rng??Math.random;return Array.from({length:amount},(()=>Math.floor(random()*255)))}const ACK_INTERVAL=9e3;const INITIAL_ACK_TIMEOUT=2e4;const SUBSEQUENT_ACK_TIMEOUT=3e4;class PromiseTimeoutError extends Error{constructor(){super("[internal_error] Comms promise timed out.")}}const REJECT_ON_NEXT_TICK_DELAY_MS=500;class PromiseWithTimeout{reset(newTimeoutMs){if(newTimeoutMs)this.timeoutMs=newTimeoutMs;this.setTimeout()}resolve(value){clearTimeout(this.timeoutId);this.resolveFn(value)}reject(reason){clearTimeout(this.timeoutId);this.rejectFn(reason)}promise(){return this.p}rejectOnNextTick(){this.timeoutId=setTimeout((()=>{this.rejectFn(new PromiseTimeoutError)}),REJECT_ON_NEXT_TICK_DELAY_MS)}setTimeout(){clearTimeout(this.timeoutId);this.timeoutId=setTimeout((()=>{this.rejectOnNextTick()}),Math.max(this.timeoutMs-REJECT_ON_NEXT_TICK_DELAY_MS,REJECT_ON_NEXT_TICK_DELAY_MS))}constructor(timeoutMs){this.timeoutMs=timeoutMs;this.p=new Promise(((resolve,reject)=>{this.resolveFn=resolve;this.rejectFn=reject}));this.setTimeout()}}const RECENT_TIMED_OUT_REQUEST_LIMIT=32;class Client{request(path,payload){const pendingRequests=this.pendingRequests;const recentTimedOutRequests=this.recentTimedOutRequests;const requestPromise=new PromiseWithTimeout(INITIAL_ACK_TIMEOUT);const requestId=this.requestIdGenerator();const resultPromise=awaitResult();const result=this.send(requestId,path,payload);if(!result.ok){this.errorService.errorException(result.error,{errorMessagePrefix:"unable to send request",tags:new Map([["type","request"],["path",path]])});requestPromise.reject(result.error)}return resultPromise;async function awaitResult(){pendingRequests.set(requestId,{path,requestPromise});try{const response=await requestPromise.promise();return Result.Ok(response)}catch(e){if(e instanceof PromiseTimeoutError){recentTimedOutRequests.set(requestId,[path,Date.now()]);if(recentTimedOutRequests.size>RECENT_TIMED_OUT_REQUEST_LIMIT)recentTimedOutRequests.delete(recentTimedOutRequests.keys().next().value);return Result.Err(new CanvaErrorClass({code:"internal_error",message:`Comms promise timed out (${path}).`}))}return Result.Err(e)}finally{pendingRequests.delete(requestId)}}}handleReply(msg){const{requestId,type}=msg;const{path,requestPromise:request}=this.pendingRequests.get(requestId)||{};if(!request){if(type!=="ack"){const[path,timestamp]=this.recentTimedOutRequests.get(requestId)??["not_recently_timed_out",undefined];const extra=timestamp!==undefined?new Map([["time_since_timeout",Date.now()-timestamp]]):undefined;this.errorService.error(`request has already been handled and resolved or was not sent from this client`,{tags:new Map([["type",type],["path",path]]),extra})}return}switch(type){case"response":request.resolve(msg.payload);return;case"ack":request.reset(SUBSEQUENT_ACK_TIMEOUT);return;case"error":this.errorService.addBreadCrumb({level:"info",category:"sandbox_comms",message:"Error response received",data:{["path"]:path??"unknown"}});const{code,message}=msg;request.reject(new CanvaErrorClass({code,message}));return;default:throw new UnreachableError(msg)}}constructor(send,errorService,requestIdGenerator=uuidv4){this.send=send;this.errorService=errorService;this.requestIdGenerator=requestIdGenerator;this.pendingRequests=new Map;this.recentTimedOutRequests=new Map}}const RequestHandlerErrorCodes={internalError:()=>"Something went wrong on our end, if this issue persists please contact us.",noHandlerForPath:path=>`No request handler configured for path: "${path}".`,handlerForPathAlreadyDefined:path=>`Handler for '${path}' is already defined.`};class RequestHandler{addErrorObserver(observer){this.errorObservers.add(observer);return()=>this.errorObservers.delete(observer)}handle(path,handler){if(this.requestHandler.has(path))throw new CanvaErrorClass({code:"internal_error",message:RequestHandlerErrorCodes.handlerForPathAlreadyDefined(path)});this.requestHandler.set(path,handler);return()=>this.requestHandler.delete(path)}async handleRequest(body){const{requestId,path,payload}=body;const handler=this.requestHandler.get(path);if(!handler){const result=this.messenger.sendError(requestId,"internal_error",RequestHandlerErrorCodes.noHandlerForPath(path));if(!result.ok)this.errorService.criticalException(result.error,{errorMessagePrefix:"unable to send error response",tags:new Map([["type","request"],["path",path]])});return}this.messenger.sendAck(requestId);const intervalId=setInterval((()=>this.messenger.sendAck(requestId)),ACK_INTERVAL);let observableError;try{const resPayload=await handler(payload);clearInterval(intervalId);this.messenger.sendResponse(requestId,resPayload)}catch(e){clearInterval(intervalId);let errorCode="internal_error";let errorMessage=RequestHandlerErrorCodes.internalError();if(e instanceof CanvaErrorClass){observableError=e;if(e.code==="internal_error")this.errorService.errorException(e,{errorMessagePrefix:"Internal error in comms handler",tags:new Map([["type","request"],["path",path]])});else{errorCode=e.code;errorMessage=e.rawMessage}}else if(this.reportNonCanvaErrors)this.errorService.errorException(e,{errorMessagePrefix:"Unexpected error type thrown from comms handler",tags:new Map([["type","request"],["path",path]])});else this.devConsole.error(e);const result=this.messenger.sendError(requestId,errorCode,errorMessage);if(!result.ok)this.errorService.criticalException(result.error,{errorMessagePrefix:"unable to send error response",tags:new Map([["type","request"],["path",path]])})}if(observableError==null)return;for(const cb of this.errorObservers)try{cb(observableError)}catch(e){this.errorService.warningException(e,{errorMessagePrefix:"Error executing errorObserver"})}}constructor(messenger,errorService,reportNonCanvaErrors,devConsole=console){this.messenger=messenger;this.errorService=errorService;this.reportNonCanvaErrors=reportNonCanvaErrors;this.devConsole=devConsole;this.requestHandler=new Map;this.errorObservers=new Set}}class SandboxCommsBase{constructor(port,errorService,reportNonCanvaErrors){this.request=(path,payload)=>this.client.request(path,payload);this.handle=(path,handler)=>this.requestHandler.handle(path,handler);this.addErrorObserver=observer=>this.requestHandler.addErrorObserver(observer);const handleMessage=message=>{switch(message.type){case"ack":case"error":case"response":this.client.handleReply(message);return;case"request":this.requestHandler.handleRequest(message);return;default:throw new UnreachableError(message)}};const messenger=new MangleSafeMessageBus(handleMessage,port,errorService.createChild("bus"));this.client=new Client(messenger.sendRequest,errorService.createChild("client"));this.requestHandler=new RequestHandler(messenger,errorService.createChild("requestHandler"),reportNonCanvaErrors)}}class MangleSafeMessageBus{sendResponse(requestId,payload){return this.bus.send({["type"]:"response",["requestId"]:requestId,["payload"]:payload})}sendError(requestId,code,message){return this.bus.send({["type"]:"error",["requestId"]:requestId,["code"]:code,["message"]:message})}sendAck(requestId){return this.bus.send({["type"]:"ack",["requestId"]:requestId})}constructor(handleMessage,port,errorService){this.handleMessage=handleMessage;this.sendRequest=(requestId,path,payload)=>this.bus.send({["type"]:"request",["requestId"]:requestId,["path"]:path,["payload"]:payload});this.onReceive=message=>{switch(message["type"]){case"ack":this.handleMessage({type:"ack",requestId:message["requestId"]});return;case"error":this.handleMessage({type:"error",requestId:message["requestId"],code:message["code"],message:message["message"]});return;case"response":this.handleMessage({type:"response",requestId:message["requestId"],payload:message["payload"]});return;case"request":this.handleMessage({type:"request",requestId:message["requestId"],path:message["path"],payload:message["payload"]});return;default:throw new UnreachableError(message)}};this.bus=new MessageBus({receive:this.onReceive},port,errorService)}}const VerifyError={MISSING_DATA:"missing 'data' field in MessageEvent",MISSING_SOURCE:"'sandboxCommsSource' is missing in MessageEvent data object",INVALID_SOURCE:"invalid source",UNKNOWN_CLIENT_ID:"unknown client id"};function createInitialiseMessage(sandboxCommsSource,clientId){return{["sandboxCommsSource"]:sandboxCommsSource,["clientId"]:clientId}}function verifyMessage(data,expectedSource,expectedClientId){if(!data)return Result.Err("missing 'data' field in MessageEvent");const msg=data;const source=msg["sandboxCommsSource"];if(!source)return Result.Err("'sandboxCommsSource' is missing in MessageEvent data object");if(source!==expectedSource)return Result.Err("invalid source");if(msg["clientId"]!==expectedClientId)return Result.Err("unknown client id");return Result.Ok()}async function connectToParent(errorService,parentOrigin,{parent,addEventListener,removeEventListener}=window,clientId){const portPromise=Promise.withResolvers();const messageHandler=({ports,data})=>{const msg=verifyMessage(data,"parent",clientId);if(!msg.ok){switch(msg.error){case VerifyError.INVALID_SOURCE:errorService.info(msg.error,{errorMessagePrefix:"failed to verify message",extra:new Map([["data.sandboxCommsSource",data?.sandboxCommsSource]])});break;case VerifyError.MISSING_DATA:case VerifyError.MISSING_SOURCE:case VerifyError.UNKNOWN_CLIENT_ID:break;default:throw new UnreachableError(msg.error)}return}if(ports.length!==1){errorService.error("invalid number of ports received from the parent");return}const[port]=ports;portPromise.resolve(port)};addEventListener("message",messageHandler);try{const initMessage=createInitialiseMessage("iframe",clientId);parent.postMessage(initMessage,parentOrigin);const port=await portPromise.promise;return Result.Ok(new SandboxCommsBase(port,errorService.createChild("comms"),false))}catch(e){return Result.Err(e)}finally{removeEventListener("message",messageHandler)}}function deserializeRequest(message_path,proto,request){if(request===undefined)throw new CanvaErrorClass({code:"internal_error",message:`${message_path}: request cannot be undefined.`});return proto.deserialize(request)}function handleMessageFromHost(comms,message_path,messageArgProto,messageHandler,responseProto){return comms.handle(message_path,(async messageObject=>{const message=deserializeRequest(message_path,messageArgProto,messageObject);const response=await messageHandler(message);if(responseProto)return responseProto.serialize(response)}))}async function runRequest(comms,messagePath,requestProto,request,responseProto){const response=await comms.request(messagePath,requestProto.serialize(request));if(!response.ok){if(response.error instanceof CanvaErrorClass)throw response.error;throw new CanvaErrorClass({code:"internal_error",message:`Something went wrong during request ${messagePath}`})}if(responseProto){if(response.value===undefined)throw new CanvaErrorClass({code:"internal_error",message:`Expected a response from ${messagePath}, but got nothing`});return responseProto.deserialize(response.value)}}const MessagePaths={INIT_TELEMETRY:"INIT_TELEMETRY",ERROR_OCCURRED:"ERROR_OCCURRED"};function isPromiseLike(p){return p!=null&&p.then!=null}function memoize(fn,{invalidateOnError}={invalidateOnError:false}){let promiseDidReject=false;let result;const memoFn=(...args)=>{Preconditions.checkArgument(args.length===0);if(result==null||invalidateOnError&&(!result.ok||promiseDidReject))try{promiseDidReject=false;result=Result.Ok(fn());if(isPromiseLike(result.value))result.value.then(null,(_e=>promiseDidReject=true))}catch(e){result=Result.Err(e)}if(result.ok)return result.value;else throw result.error};return memoFn}function memoize1(fn){const cache=new WeakMap;const memoFn=(key,...rest)=>{Preconditions.checkArgument(rest.length===0);if(!cache.has(key))cache.set(key,fn(key));return cache.get(key)};return memoFn}const MessageKind={CONCRETE:1,ONEOF:2};const FieldLabel={CONSTANT:1,REQUIRED:2,OPTIONAL:3,REPEATED:4,MAP:5};const FieldKind={PRIMITIVE:1,MESSAGE:2,ENUM:3};const makeType=t=>t;const ProtoType={STRING:makeType({typeOfValue:"string"}),BOOLEAN:makeType({typeOfValue:"boolean",defaultValue:false,fixedSize:1}),DOUBLE:makeType({typeOfValue:"number",defaultValue:0,fixedSize:8}),INT32:makeType({typeOfValue:"number",defaultValue:0}),INT64:makeType({typeOfValue:"number",defaultValue:0}),BYTES:makeType({typeOfValue:"Uint8Array"})};function makeFieldConfig(tag,fieldLabel,typeOfValue,jsonFullKey,jsonFullValue,value,defaults,defaultField,defaultValue,obj,typeOfKey){return{tag,fieldLabel,typeOfValue,jsonFullKey,jsonFullValue,value,defaults,default:defaultField,defaultValue,obj,typeOfKey}}function constantField(params){const{tag,jsonFullKeyOrJsonMiniKey,jsonFullValue,value,defaults}=params;const jsonFullKey=jsonFullKeyOrJsonMiniKey===DISCRIMINATOR_JSON_MINI_KEY?undefined:jsonFullKeyOrJsonMiniKey;return makeFieldConfig(tag,FieldLabel.CONSTANT,"string",jsonFullKey,jsonFullValue,value,defaults,undefined,undefined,undefined,undefined)}function requiredField(valueType,jsonFullKey,tag,def){return makeFieldConfig(tag,FieldLabel.REQUIRED,valueType.typeOfValue,jsonFullKey,undefined,undefined,undefined,def!=null?def:valueType.defaultValue,valueType.defaultValue,undefined,undefined)}function optionalField(valueType,jsonFullKey,tag){return makeFieldConfig(tag,FieldLabel.OPTIONAL,valueType.typeOfValue,jsonFullKey,undefined,undefined,undefined,undefined,valueType.defaultValue,undefined,undefined)}function repeatedField(valueType,jsonFullKey,tag){return makeFieldConfig(tag,FieldLabel.REPEATED,valueType.typeOfValue,jsonFullKey,undefined,undefined,undefined,undefined,undefined,undefined,undefined)}function mapField(keyType,valueType){return(tagOrJsonFullKey,tagOrObj,maybeObj)=>{const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);let typeOfValue;if(valueType==="object")typeOfValue="object";else if(valueType==="enum")typeOfValue="string";else typeOfValue=valueType.typeOfValue;return makeFieldConfig(tag,FieldLabel.MAP,typeOfValue,jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,keyType.typeOfValue)}}class Proto{static constantString(jsonFullKeyOrJsonMiniKey,jsonFullValueOrTag,tagOrValue,maybeValue){const{tag,jsonFullKey:jsonFullValue,other1:value}=getOptions(jsonFullValueOrTag,tagOrValue,maybeValue);return constantField({tag,jsonFullKeyOrJsonMiniKey,jsonFullValue,value,defaults:false})}static constantStringWithDefault(jsonFullKeyOrJsonMiniKey,jsonFullValueOrTag,tagOrValue,maybeValue){const{tag,jsonFullKey:jsonFullValue,other1:value}=getOptions(jsonFullValueOrTag,tagOrValue,maybeValue);return constantField({tag,jsonFullKeyOrJsonMiniKey,jsonFullValue,value,defaults:true})}static requiredObject(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.REQUIRED,"object",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static optionalObject(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.OPTIONAL,"object",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static repeatedObject(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.REPEATED,"object",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static requiredStringEnum(tagOrJsonFullKey,tagOrObj,objOrDef,maybeDef){const{tag,jsonFullKey,other1:obj,other2:def}=getOptions(tagOrJsonFullKey,tagOrObj,objOrDef,maybeDef);return makeFieldConfig(tag,FieldLabel.REQUIRED,"string",jsonFullKey,undefined,undefined,undefined,def,undefined,obj,undefined)}static optionalStringEnum(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.OPTIONAL,"string",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static repeatedStringEnum(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.REPEATED,"string",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static createMessage(schema,options={}){const init=memoize((()=>{const fields=schema();const fieldNames=Object.keys(fields);const fieldsByTag={};const constantsByTag={};for(let i=0;i{throw new TypeError(`Unproducible oneof case ${pathTrace(path)}`)}:(message,path)=>{if(message==null||typeof message!=="object")throw new TypeError(`Expected type object, found: ${moreSpecificTypeof(message)} ${pathTrace(path)}`);const{fieldMetadata}=init();const res={};for(let i=0;i{const config=schema();const discriminatorKey=Object.keys(config)[0];let discriminatorTag;let discriminatorJsonKeyEncodings;const nameToObject=new Map;const serializedToObject=new Map;const tagToObject=new Map;for(let i=0;i{const{discriminatorKey,nameToObject}=init();const type=t[discriminatorKey];const obj=nameToObject.get(type);if(!obj)throw new TypeError(`Unknown oneof deserialized case: ${JSON.stringify(type)} ${pathTrace(path)}`);return obj.serializeWithPath(t,path)};const deserializeWithPath=(o,path)=>{const{serializedToObject,discriminatorJsonKeyEncodings,defaultObject}=init();const{primaryJsonKey,secondaryJsonKey}=discriminatorJsonKeyEncodings;let type=o[primaryJsonKey];if(type==null&&secondaryJsonKey)type=o[secondaryJsonKey];if(type==null&&defaultObject)return defaultObject.deserializeWithPath(o,path);const obj=serializedToObject.get(type);if(!obj)throw new TypeError(`Unknown oneof serialized case: ${JSON.stringify(type)} ${pathTrace(path)}`);return obj.deserializeWithPath(o,path)};return{init,serialize:t=>serializeWithPath(t,[]),serializeWithPath,deserialize:o=>deserializeWithPath(o,[]),deserializeWithPath}}static createEnumUtil(schema,baseNumber=0,options={}){const init=memoize((()=>{const config=schema();const values=[];const serializedToValue=new Map;const valueToSerialized=new Map;const valueToProtobufSerialized=new Map;const protobufSerializedToValue=new Map;const unproducible=new Set;let i=0;let index=1;while(i{const{unproducible}=init();if(unproducible&&unproducible.has(value))throw new TypeError(`Unproducible enum value: ${JSON.stringify(value)} ${path?pathTrace(path):""}`);const serialized=map.get(value);if(serialized==null)throw new TypeError(`The proto enum serializer failed to serialize value ${JSON.stringify(value)} into JSON.\nIt does not recognize value ${JSON.stringify(value)} as a valid member of the TypeScript enum.\n${path?pathTrace(path):""}`);return serialized};const deserializeWithPath=(jsonValue,path)=>{const value=init().serializedToValue.get(jsonValue);if(value==null)throw new TypeError(`The proto enum deserializer failed to deserialize JSON ${JSON.stringify(jsonValue)} into an enum value.\nIt does not recognize JSON ${JSON.stringify(jsonValue)} as a valid JSON value encoding of the enum.\n${pathTrace(path)}`);return value};return{values:()=>init().values,producibleValues:()=>{const{values,unproducible}=init();if(unproducible==null)return values;return values.filter((value=>!unproducible.has(value)))},serialize:value=>getSerialized(value,init().valueToSerialized,[]),serializeWithPath:(value,path)=>getSerialized(value,init().valueToSerialized,path),deserialize:jsonValue=>deserializeWithPath(jsonValue,[]),deserializeWithPath}}}Proto.requiredDouble=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.DOUBLE,jsonFullKey,tag,other1)};Proto.requiredInt32=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.INT32,jsonFullKey,tag,other1)};Proto.requiredInt64=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.INT64,jsonFullKey,tag,other1)};Proto.optionalDouble=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.DOUBLE,jsonFullKey,tag)};Proto.optionalInt32=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.INT32,jsonFullKey,tag)};Proto.optionalInt64=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.INT64,jsonFullKey,tag)};Proto.repeatedDouble=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.DOUBLE,jsonFullKey,tag)};Proto.repeatedInt32=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.INT32,jsonFullKey,tag)};Proto.repeatedInt64=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.INT64,jsonFullKey,tag)};Proto.requiredString=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.STRING,jsonFullKey,tag,other1)};Proto.optionalString=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.STRING,jsonFullKey,tag)};Proto.repeatedString=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.STRING,jsonFullKey,tag)};Proto.requiredBoolean=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.BOOLEAN,jsonFullKey,tag,other1)};Proto.optionalBoolean=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.BOOLEAN,jsonFullKey,tag)};Proto.repeatedBoolean=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.BOOLEAN,jsonFullKey,tag)};Proto.requiredBytes=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.BYTES,jsonFullKey,tag,other1)};Proto.optionalBytes=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.BYTES,jsonFullKey,tag)};Proto.repeatedBytes=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.BYTES,jsonFullKey,tag)};Proto.booleanInt64Map=mapField(ProtoType.BOOLEAN,ProtoType.INT64);Proto.int32Int32Map=mapField(ProtoType.INT32,ProtoType.INT32);Proto.int32Int64Map=mapField(ProtoType.INT32,ProtoType.INT64);Proto.int32BoolMap=mapField(ProtoType.INT32,ProtoType.BOOLEAN);Proto.int32DoubleMap=mapField(ProtoType.INT32,ProtoType.DOUBLE);Proto.int32StringMap=mapField(ProtoType.INT32,ProtoType.STRING);Proto.int32StringEnumMap=mapField(ProtoType.INT32,"enum");Proto.int32ObjectMap=mapField(ProtoType.INT32,"object");Proto.int32BytesMap=mapField(ProtoType.INT32,ProtoType.BYTES);Proto.int64Int32Map=mapField(ProtoType.INT64,ProtoType.INT32);Proto.int64Int64Map=mapField(ProtoType.INT64,ProtoType.INT64);Proto.int64BooleanMap=mapField(ProtoType.INT64,ProtoType.BOOLEAN);Proto.int64DoubleMap=mapField(ProtoType.INT64,ProtoType.DOUBLE);Proto.int64StringMap=mapField(ProtoType.INT64,ProtoType.STRING);Proto.int64StringEnumMap=mapField(ProtoType.INT64,"enum");Proto.int64ObjectMap=mapField(ProtoType.INT64,"object");Proto.int64BytesMap=mapField(ProtoType.INT64,ProtoType.BYTES);Proto.doubleInt32Map=mapField(ProtoType.DOUBLE,ProtoType.INT32);Proto.doubleInt64Map=mapField(ProtoType.DOUBLE,ProtoType.INT64);Proto.doubleBoolMap=mapField(ProtoType.DOUBLE,ProtoType.BOOLEAN);Proto.doubleDoubleMap=mapField(ProtoType.DOUBLE,ProtoType.DOUBLE);Proto.doubleStringMap=mapField(ProtoType.DOUBLE,ProtoType.STRING);Proto.doubleStringEnumMap=mapField(ProtoType.DOUBLE,"enum");Proto.doubleObjectMap=mapField(ProtoType.DOUBLE,"object");Proto.doubleBytesMap=mapField(ProtoType.DOUBLE,ProtoType.BYTES);Proto.stringInt32Map=mapField(ProtoType.STRING,ProtoType.INT32);Proto.stringInt64Map=mapField(ProtoType.STRING,ProtoType.INT64);Proto.stringBooleanMap=mapField(ProtoType.STRING,ProtoType.BOOLEAN);Proto.stringDoubleMap=mapField(ProtoType.STRING,ProtoType.DOUBLE);Proto.stringStringMap=mapField(ProtoType.STRING,ProtoType.STRING);Proto.stringStringEnumMap=mapField(ProtoType.STRING,"enum");Proto.stringObjectMap=mapField(ProtoType.STRING,"object");Proto.stringBytesMap=mapField(ProtoType.STRING,ProtoType.BYTES);function deriveFieldMetadata(fields,dualDeserializationConfig){return Object.entries(fields).map((([name,config])=>{const fieldEncodings=deriveFieldEncodings(config,dualDeserializationConfig);return{config,name,primaryJsonKey:fieldEncodings.keyEncodings.primaryJsonKey,secondaryJsonKey:fieldEncodings.keyEncodings.secondaryJsonKey,primaryJsonValue:fieldEncodings.valueEncodings?.primaryJsonValue,secondaryJsonValue:fieldEncodings.valueEncodings?.secondaryJsonValue}}))}function deriveFieldEncodings(fieldConfig,dualDeserializationConfig){let valueEncodings;let jsonMiniKey=toJsonMini(fieldConfig.tag-1);if(fieldConfig.fieldLabel===FieldLabel.CONSTANT){const{primary:primaryJsonValue,secondary:secondaryJsonValue}=choosePrimaryAndSecondaryJSONFromConfig(jsonMiniKey,fieldConfig.jsonFullValue,dualDeserializationConfig);jsonMiniKey=DISCRIMINATOR_JSON_MINI_KEY;valueEncodings={primaryJsonValue,secondaryJsonValue}}const{primary:primaryJsonKey,secondary:secondaryJsonKey}=choosePrimaryAndSecondaryJSONFromConfig(jsonMiniKey,fieldConfig.jsonFullKey,dualDeserializationConfig);const keyEncodings={primaryJsonKey,secondaryJsonKey};return{keyEncodings,valueEncodings}}function choosePrimaryAndSecondaryJSONFromConfig(jsonMini,jsonFull,dualDeserializationConfig){if(!jsonFull){if(dualDeserializationConfig!==undefined)throw new Error("Dual Deserialization config templated but JSON full key/value wasn't");return{primary:jsonMini,secondary:undefined}}if(dualDeserializationConfig===undefined)return{primary:jsonFull,secondary:undefined};else if(dualDeserializationConfig===0)return{primary:jsonMini,secondary:jsonFull};else if(dualDeserializationConfig===1)return{primary:jsonFull,secondary:jsonMini};throw new Error("function should have been exhaustive, but wasn't")}function makeRepeatedTypeError(keyEncodings,value,expectedType,path){return new TypeError(`Expected repeated ${expectedType} value for key ${expectedKeys(keyEncodings)}, found: ${moreSpecificTypeof(value)} ${pathTrace(path)}`)}function makeOptionalTypeError(keyEncodings,value,expectedType,path){return new TypeError(`Expected optional ${expectedType} value for key ${expectedKeys(keyEncodings)}, found: ${moreSpecificTypeof(value)} ${pathTrace(path)}`)}function makeRequiredTypeError(keyEncodings,value,expectedType,path,index){const atIndex=index!==undefined?` at index ${index}`:"";return new TypeError(`Expected ${expectedType} value${atIndex} for key ${expectedKeys(keyEncodings)}, found: ${moreSpecificTypeof(value)} ${pathTrace(path)}`)}function expectedKeys(keyEncodings){const{primaryJsonKey,secondaryJsonKey}=keyEncodings;if(secondaryJsonKey)return`either "${primaryJsonKey}" OR "${secondaryJsonKey}"`;return`"${primaryJsonKey}"`}function expectedValues(valueEncodings){const{primaryJsonValue,secondaryJsonValue}=valueEncodings;if(secondaryJsonValue)return`either "${primaryJsonValue}" OR "${secondaryJsonValue}"`;return`"${primaryJsonValue}"`}function pathTrace(path){return`(path: .${path.join(".")})`}function moreSpecificTypeof(value){if(value===null)return"null";if(Array.isArray(value))return"array";return typeof value}const DualDeserializationConfig={MINI_PRIMARY_FULL_SECONDARY:0,FULL_PRIMARY_MINI_SECONDARY:1};const DISCRIMINATOR_JSON_MINI_KEY="A?";const JSON_MINI_ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function toJsonMini(x){if(x0){builder.push(JSON_MINI_ALPHABET.charAt(x%JSON_MINI_ALPHABET.length));x=Math.floor(x/JSON_MINI_ALPHABET.length)}return builder.reverse().join("")}}function getOptions(tagOrJsonFullKey,tagOrOther1,other1OrOther2,maybeOther2){if(typeof tagOrJsonFullKey==="string")return{jsonFullKey:tagOrJsonFullKey,tag:tagOrOther1,other1:other1OrOther2,other2:maybeOther2};else return{tag:tagOrJsonFullKey,other1:tagOrOther1,other2:other1OrOther2}}function isCorrectWireType(value,typeOfValue){return typeof value===typeOfValue||isCorrectBytesWireType(value,typeOfValue)}function isCorrectBytesWireType(value,typeOfValue){return typeOfValue==="Uint8Array"&&typeof value==="string"}function toBase64(bytes){const binString=Array.from(bytes,(byte=>String.fromCodePoint(byte))).join("");return btoa(binString)}function fromBase64(base64){return Uint8Array.from(atob(base64),(m=>m.codePointAt(0)))}const InitTelemetryRequest=Proto.createMessage((()=>({})));const InitTelemetryResponse=Proto.createMessage((()=>({documentId:Proto.optionalString("documentId",1),elementId:Proto.optionalString("elementId",2)})),{dualDeserializationConfig:DualDeserializationConfig.MINI_PRIMARY_FULL_SECONDARY});const ErrorOccurredRequest=Proto.createMessage((()=>({errorTimestamp:Proto.requiredInt64(1),errorId:Proto.requiredString(2),message:Proto.requiredString(3)})));const ErrorOccurredResponse=Proto.createMessage((()=>({})));const TELEMETRY_CLIENT_ID="canva-code-telemetry-sdk";function setupTelemetryRequestHandlers(comms,handler){handleMessageFromHost(comms,MessagePaths.INIT_TELEMETRY,InitTelemetryRequest,(request=>handler.handleInitTelemetry(request)),InitTelemetryResponse);handleMessageFromHost(comms,MessagePaths.ERROR_OCCURRED,ErrorOccurredRequest,(request=>handler.handleErrorOccurred(request)),ErrorOccurredResponse)}class TelemetryClientComms{async sendInitTelemetry(request){const result=await this.comms.request(MessagePaths.INIT_TELEMETRY,InitTelemetryRequest.serialize(request));const value=extractValue(result,MessagePaths.INIT_TELEMETRY);return InitTelemetryResponse.deserialize(value)}async sendErrorOccurred(request){const result=await this.comms.request(MessagePaths.ERROR_OCCURRED,ErrorOccurredRequest.serialize(request));const value=extractValue(result,MessagePaths.ERROR_OCCURRED);return ErrorOccurredResponse.deserialize(value)}constructor(comms){this.comms=comms}}function extractValue(result,messagePath){if(!result.ok)throw new Error(`Encountered an error while sending ${messagePath} request: ${result.error}`);if(result.value==null)throw new Error(`${messagePath}: Result cannot be empty`);return result.value}function createEndpointUrl(path,baseUrl){const urlString=baseUrl??window.location.href;let normalizedBase;try{const url=new URL(urlString);url.hash="";url.search="";const pathname=url.pathname;const lastSegment=pathname.split("/").pop()??"";if(lastSegment.toLowerCase().endsWith(".html")){const pathParts=pathname.split("/");pathParts.pop();url.pathname=pathParts.join("/")||"/"}normalizedBase=url.toString()}catch{normalizedBase=urlString.split("#")[0].split("?")[0]}if(normalizedBase.endsWith("/"))normalizedBase=normalizedBase.slice(0,-1);const normalizedPath=path.startsWith("/")?path:"/"+path;return normalizedBase+normalizedPath}function createEndpointUrlWithParams(path,params,baseUrl){const endpointUrl=createEndpointUrl(path,baseUrl);const url=new URL(endpointUrl);if(params){for(const[key,value]of Object.entries(params))if(value!==undefined)url.searchParams.set(key,value)}return url.toString()}const DeploymentGroup={STABLE:1,CANARY_CONTROL:2,UNSTABLE:3};const DeploymentGroupUtil=Proto.createEnumUtil((()=>[0,1,2]));const CodeletBootstrap=Proto.createMessage((()=>({deploymentGroup:Proto.requiredStringEnum(1,DeploymentGroupUtil),releaseId:Proto.requiredString(2)})));const TelemetrySeverity={DEBUG:1,INFO:2,WARNING:3,ERROR:4,FATAL:5};const TelemetrySeverityUtil=Proto.createEnumUtil((()=>[0,1,2,3,4]));const TelemetryLogEntry=Proto.createMessage((()=>({eventId:Proto.requiredString(1),message:Proto.requiredString(2),severity:Proto.requiredStringEnum(3,TelemetrySeverityUtil),timestamp:Proto.requiredInt64(4),isSystem:Proto.requiredBoolean(5),args:Proto.optionalString(6),stackTrace:Proto.optionalString(7)})));const SendTelemetryLogsRequest=Proto.createMessage((()=>({documentId:Proto.optionalString(1),elementId:Proto.optionalString(2),logs:Proto.repeatedObject(3,TelemetryLogEntry),sessionId:Proto.optionalString(4),deploymentGroup:Proto.optionalStringEnum(5,DeploymentGroupUtil),releaseId:Proto.optionalString(6)})));const SendTelemetryLogsResponse=Proto.createMessage((()=>({})));const DEFAULT_MAX_BEACON_PAYLOAD_BYTES=61440;const DEFAULT_MAX_EVENTS_PER_REQUEST=25;const DEFAULT_CONFIG={maxBufferSize:DEFAULT_MAX_EVENTS_PER_REQUEST,maxAbsoluteBufferSize:1e3,flushIntervalMs:2e3,maxConsecutiveFailures:3,maxBeaconPayloadBytes:DEFAULT_MAX_BEACON_PAYLOAD_BYTES,maxEventsPerRequest:DEFAULT_MAX_EVENTS_PER_REQUEST};class FetchTelemetryService{setDocumentContext(documentId,elementId){this.documentId=documentId;this.elementId=elementId}setReleaseContext(deploymentGroup,releaseId){this.deploymentGroup=deploymentGroup;this.releaseId=releaseId}addLog(entry){this.buffer.push(entry);while(this.buffer.length>this.config.maxAbsoluteBufferSize)this.buffer.shift();if(this.buffer.length>=this.config.maxBufferSize)this.flush()}async flush(){if(this.buffer.length===0||this.isSending)return;if(this.consecutiveFailures>=this.config.maxConsecutiveFailures)return;this.isSending=true;const logsToSend=[...this.buffer];this.buffer=[];try{const batches=this.splitIntoBatches(logsToSend);for(const batch of batches){const request=this.createRequest(batch);const response=await fetch(this.telemetryEndpoint,{method:"POST",headers:{["Content-Type"]:"application/json"},body:JSON.stringify(SendTelemetryLogsRequest.serialize(request))});if(response.ok)this.consecutiveFailures=0;else{const unsentIndex=logsToSend.indexOf(batch[0]);const unsentLogs=logsToSend.slice(unsentIndex);this.buffer=[...unsentLogs,...this.buffer];this.consecutiveFailures++;return}}}catch{this.buffer=[...logsToSend,...this.buffer];this.consecutiveFailures++}finally{this.isSending=false}}flushSync(){if(this.buffer.length===0)return true;if(this.consecutiveFailures>=this.config.maxConsecutiveFailures)return false;const logsToSend=this.trimLogsToFitPayloadLimit(this.buffer);if(logsToSend.length===0)return false;const batches=this.splitIntoBatches(logsToSend);let allSucceeded=true;for(const batch of batches){const request=this.createRequest(batch);const blob=new Blob([JSON.stringify(SendTelemetryLogsRequest.serialize(request))],{type:"application/json"});const success=navigator.sendBeacon(this.telemetryEndpoint,blob);if(!success){allSucceeded=false;this.consecutiveFailures++;break}}if(allSucceeded){this.buffer=[];this.consecutiveFailures=0}return allSucceeded}dispose(){if(this.flushIntervalId!=null){clearInterval(this.flushIntervalId);this.flushIntervalId=null}}startFlushInterval(){this.flushIntervalId=setInterval((()=>{this.flush()}),this.config.flushIntervalMs)}splitIntoBatches(logs){const batches=[];for(let i=0;i1)result.push({...entry,message:`${entry.message} (x${count})`});else result.push(entry);return result.sort(((a,b)=>a.timestamp-b.timestamp))}trimToFitSize(logs){const trimmedLogs=[...logs];let payloadSize=this.basePayloadSize;for(let i=trimmedLogs.length-1;i>=0;i--){const size=this.calculateEntrySize(trimmedLogs[i]);if(payloadSize+size<=this.config.maxBeaconPayloadBytes)payloadSize+=size;else if(i{if(val===undefined)return"[undefined]";if(typeof val==="function")return`[Function: ${val.name||"anonymous"}]`;if(typeof val==="symbol")return val.toString();if(typeof val==="bigint")return`${val.toString()}n`;if(val instanceof Error)return{name:val.name,message:val.message,stack:val.stack};if(val instanceof RegExp)return val.toString();if(val instanceof Date)return val.toISOString();if(val!=null&&typeof val==="object"){if(seen.has(val))return"[Circular]";seen.add(val)}return val};try{return JSON.stringify(value,replacer)}catch{return String(value)}}function unknownToString(value){if(value===undefined)return"undefined";if(value==null)return"null";if(typeof value==="string")return value;if(typeof value==="number"||typeof value==="boolean")return String(value);if(typeof value==="bigint")return`${value.toString()}n`;if(typeof value==="symbol")return value.toString();if(typeof value==="function")return`[Function: ${value.name||"anonymous"}]`;if(value instanceof Error)return value.message;return safeStringify(value)}function generateEventId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}function extractMessage(error){if(typeof error==="string")return error;if(error instanceof Error)return error.message;return String(error)}function extractStackTrace(error){if(error instanceof Error)return error.stack;return undefined}const IS_SYSTEM_KEY="isSystem";function extractIsSystem(extra){if(extra===undefined||typeof extra==="string")return false;const extraMap=extra.extra;if(extraMap===undefined)return false;return extraMap.get(IS_SYSTEM_KEY)===true||extraMap.get(IS_SYSTEM_KEY)==="true"}function serializeExtra(extra){if(extra===undefined)return undefined;if(typeof extra==="string")return safeStringify({errorMessagePrefix:extra});const obj={};if(extra.fingerprint!==undefined)obj["fingerprint"]=extra.fingerprint;if(extra.errorMessagePrefix!==undefined)obj["errorMessagePrefix"]=extra.errorMessagePrefix;if(extra.tags!==undefined)obj["tags"]=Object.fromEntries(extra.tags);if(extra.userFlow!==undefined)obj["userFlow"]=extra.userFlow;if(extra.extra!==undefined)obj["extra"]=Object.fromEntries(extra.extra);if(extra.sampleRate!==undefined)obj["sampleRate"]=extra.sampleRate;return safeStringify(obj)}function mapMethodToSeverity(method){switch(method){case"debug":return TelemetrySeverity.DEBUG;case"log":case"info":return TelemetrySeverity.INFO;case"warn":return TelemetrySeverity.WARNING;case"error":return TelemetrySeverity.ERROR;default:return TelemetrySeverity.INFO}}class CloudflareErrorService{createChild(name){const child=new CloudflareErrorService(`${this.context}:${name}`,this.telemetryService,this.originalConsole,this);child.documentId=this.documentId;child.elementId=this.elementId;child.beforeReportHandlers=this.beforeReportHandlers;this.children.push(child);return child}withOfflineStatus(_offlineStatusStore,_initialOfflineStatus){}setContext(context){this.logInternal("debug",false,"context set",safeStringify(context))}setTag(key,value,_scope){this.logInternal("debug",false,`tag set: ${key}=${value}`)}addBeforeSendHandler(_handler){}addBeforeReportHandler(handler){this.beforeReportHandlers.push(handler)}setFilters(_fns){}setSensitiveStrings(_sensitiveStrings){}addBreadCrumb(breadCrumb){this.logInternal("debug",false,"breadcrumb added",safeStringify(breadCrumb))}debug(error,extra){this.beforeReportHandlers.forEach((handler=>handler("debug",error,extra)));const isSystem=extractIsSystem(extra);this.logInternal("debug",isSystem,extractMessage(error),serializeExtra(extra))}info(error,extra){this.beforeReportHandlers.forEach((handler=>handler("info",error,extra)));const isSystem=extractIsSystem(extra);this.logInternal("info",isSystem,extractMessage(error),serializeExtra(extra))}warning(error,extra){this.beforeReportHandlers.forEach((handler=>handler("warning",error,extra)));const isSystem=extractIsSystem(extra);this.logInternal("warn",isSystem,extractMessage(error),serializeExtra(extra))}warningException(error,extra){this.beforeReportHandlers.forEach((handler=>handler("warning",error,extra)));const isSystem=extractIsSystem(extra);this.logInternal("warn",isSystem,extractMessage(error),serializeExtra(extra),extractStackTrace(error))}error(error,extra){this.beforeReportHandlers.forEach((handler=>handler("error",error,extra)));const isSystem=extractIsSystem(extra);this.logInternal("error",isSystem,extractMessage(error),serializeExtra(extra),extractStackTrace(error))}errorException(error,extra){this.beforeReportHandlers.forEach((handler=>handler("error",error,extra)));const isSystem=extractIsSystem(extra);this.logInternal("error",isSystem,extractMessage(error),serializeExtra(extra),extractStackTrace(error))}critical(error,extra){this.beforeReportHandlers.forEach((handler=>handler("fatal",error,extra)));const isSystem=extractIsSystem(extra);this.logInternalCritical(isSystem,extractMessage(error),serializeExtra(extra),extractStackTrace(error))}criticalException(error,extra){this.beforeReportHandlers.forEach((handler=>handler("fatal",error,extra)));const isSystem=extractIsSystem(extra);this.logInternalCritical(isSystem,extractMessage(error),serializeExtra(extra),extractStackTrace(error))}logInternal(method,isSystem,message,args,stackTrace){const fullMessage=`[CLIENT (${this.context})] ${message}`;if(args!==undefined)this.originalConsole[method](fullMessage,args);else this.originalConsole[method](fullMessage);const entry=new TelemetryLogEntry({eventId:generateEventId(),message:fullMessage,severity:mapMethodToSeverity(method),timestamp:Date.now(),isSystem,args,stackTrace});this.telemetryService.addLog(entry)}logInternalCritical(isSystem,message,args,stackTrace){const fullMessage=`[CLIENT (${this.context})] ${message}`;if(args!==undefined)this.originalConsole.error(fullMessage,args);else this.originalConsole.error(fullMessage);const entry=new TelemetryLogEntry({eventId:generateEventId(),message:fullMessage,severity:TelemetrySeverity.FATAL,timestamp:Date.now(),isSystem,args,stackTrace});this.telemetryService.addLog(entry)}constructor(context,telemetryService,originalConsole,parent){this.context=context;this.telemetryService=telemetryService;this.originalConsole=originalConsole;this.parent=parent;this.children=[];this.beforeReportHandlers=[]}}const SYSTEM_LOG_MARKER=Symbol("canvaSystemLog");const TARGET_ORIGIN="*";function argsToMessage(args){return args.map((arg=>{if(typeof arg==="string")return arg;if(arg instanceof Error)return arg.message;if(arg===SYSTEM_LOG_MARKER)return"";return unknownToString(arg)})).filter((s=>s&&s.length>0)).join(" ")}function extractStackTraceFromArgs(args){for(const arg of args){if(arg instanceof Error&&arg.stack)return arg.stack}return undefined}function serializeArgs(args){const filtered=args.filter((arg=>arg!==SYSTEM_LOG_MARKER));if(filtered.length<=1)return undefined;return safeStringify(filtered.slice(1))}class TelemetrySdk{setupReleaseContext(){const bootstrapObject=window.__codeletBootstrap__;if(bootstrapObject==null)return;try{const bootstrap=CodeletBootstrap.deserialize(bootstrapObject);this.telemetryService.setReleaseContext(bootstrap.deploymentGroup,bootstrap.releaseId)}catch(e){this.errorService.errorException(e,{extra:new Map([[IS_SYSTEM_KEY,true]])})}}async setupParentCommunication(){try{const result=await this.connectToParent(this.errorService,TARGET_ORIGIN,window,TELEMETRY_CLIENT_ID);if(!result.ok){this.errorService.error("Failed to connect to parent for telemetry");return}this.telemetryClientComms=this.createTelemetryClientComms(result.value);const initResponse=await this.telemetryClientComms.sendInitTelemetry(new InitTelemetryRequest);this.documentId=initResponse.documentId;this.elementId=initResponse.elementId;this.telemetryService.setDocumentContext(this.documentId,this.elementId);this.isInitialized=true;this.flushPendingErrorNotifications();this.errorService.info("Telemetry SDK initialized",{extra:new Map([[IS_SYSTEM_KEY,true]])})}catch(e){this.errorService.errorException(e,{extra:new Map([[IS_SYSTEM_KEY,true]])})}}setupConsoleHandlers(){console.debug=(...args)=>{const isSystem=this.detectSystemLog(args);this.captureConsole(TelemetrySeverity.DEBUG,args,isSystem);this.originalConsole.debug(...args)};console.log=(...args)=>{const isSystem=this.detectSystemLog(args);this.captureConsole(TelemetrySeverity.INFO,args,isSystem);this.originalConsole.log(...args)};console.info=(...args)=>{const isSystem=this.detectSystemLog(args);this.captureConsole(TelemetrySeverity.INFO,args,isSystem);this.originalConsole.info(...args)};console.warn=(...args)=>{const isSystem=this.detectSystemLog(args);this.captureConsole(TelemetrySeverity.WARNING,args,isSystem);this.originalConsole.warn(...args)};console.error=(...args)=>{const isSystem=this.detectSystemLog(args);const eventId=this.captureConsole(TelemetrySeverity.ERROR,args,isSystem);if(!isSystem&&eventId)this.notifyErrorOccurred(argsToMessage(args),eventId);this.originalConsole.error(...args)}}setupGlobalErrorHandlers(){this.originalOnError=window.onerror;this.originalOnUnhandledRejection=window.onunhandledrejection;const originalOnError=this.originalOnError;const originalOnUnhandledRejection=this.originalOnUnhandledRejection;window.onerror=(message,source,lineno,colno,error)=>{const eventId=uuidv4();const messageStr=typeof message==="string"?message:"Unknown error";const entry=new TelemetryLogEntry({eventId,message:messageStr,severity:TelemetrySeverity.ERROR,timestamp:Date.now(),isSystem:false,args:JSON.stringify({source,lineno,colno}),stackTrace:error?.stack});this.telemetryService.addLog(entry);this.notifyErrorOccurred(messageStr,eventId);if(typeof originalOnError==="function")return originalOnError.call(window,message,source,lineno,colno,error)};window.onunhandledrejection=event=>{const eventId=uuidv4();const reason=event.reason;const messageStr=reason instanceof Error?reason.message:String(reason??"Unhandled promise rejection");const entry=new TelemetryLogEntry({eventId,message:messageStr,severity:TelemetrySeverity.ERROR,timestamp:Date.now(),isSystem:false,stackTrace:reason instanceof Error?reason.stack:undefined});this.telemetryService.addLog(entry);this.notifyErrorOccurred(messageStr,eventId);if(typeof originalOnUnhandledRejection==="function")originalOnUnhandledRejection.call(window,event)}}setupBrowserApiHandlers(){this.originalSetTimeout=window.setTimeout;this.originalSetInterval=window.setInterval;this.originalRequestAnimationFrame=window.requestAnimationFrame;const originalSetTimeout=this.originalSetTimeout;const originalSetInterval=this.originalSetInterval;const originalRequestAnimationFrame=this.originalRequestAnimationFrame;window.setTimeout=(handler,timeout,...args)=>{if(typeof handler==="function"){const wrappedHandler=(...runtimeArgs)=>{try{handler(...runtimeArgs)}catch(e){this.handleBrowserApiError(e,"setTimeout");throw e}};return originalSetTimeout.call(window,wrappedHandler,timeout,...args)}return originalSetTimeout.call(window,handler,timeout,...args)};window.setInterval=(handler,timeout,...args)=>{if(typeof handler==="function"){const wrappedHandler=(...runtimeArgs)=>{try{handler(...runtimeArgs)}catch(e){this.handleBrowserApiError(e,"setInterval");throw e}};return originalSetInterval.call(window,wrappedHandler,timeout,...args)}return originalSetInterval.call(window,handler,timeout,...args)};window.requestAnimationFrame=callback=>{const wrappedCallback=time=>{try{callback(time)}catch(e){this.handleBrowserApiError(e,"requestAnimationFrame");throw e}};return originalRequestAnimationFrame.call(window,wrappedCallback)}}setupPageUnloadHandler(){this.visibilityChangeHandler=()=>{if(document.visibilityState==="hidden")this.telemetryService.flushSync()};this.pagehideHandler=()=>{this.telemetryService.flushSync()};document.addEventListener("visibilitychange",this.visibilityChangeHandler);window.addEventListener("pagehide",this.pagehideHandler)}detectSystemLog(args){return args.some((arg=>arg===SYSTEM_LOG_MARKER))}captureConsole(severity,args,isSystem){const eventId=uuidv4();const entry=new TelemetryLogEntry({eventId,message:argsToMessage(args),severity,timestamp:Date.now(),isSystem,args:serializeArgs(args),stackTrace:extractStackTraceFromArgs(args)});this.telemetryService.addLog(entry);return eventId}handleBrowserApiError(error,source){const eventId=uuidv4();const message=error instanceof Error?error.message:String(error);const entry=new TelemetryLogEntry({eventId,message:`[${source}] ${message}`,severity:TelemetrySeverity.ERROR,timestamp:Date.now(),isSystem:false,stackTrace:error instanceof Error?error.stack:undefined});this.telemetryService.addLog(entry);this.notifyErrorOccurred(message,eventId)}notifyErrorOccurred(summary,eventId){if(!this.isInitialized){this.pendingErrorNotifications.push({summary,eventId});return}if(!this.telemetryClientComms)return;this.telemetryClientComms.sendErrorOccurred(new ErrorOccurredRequest({errorTimestamp:Date.now(),errorId:eventId,message:summary}))}flushPendingErrorNotifications(){if(!this.telemetryClientComms)return;for(const notification of this.pendingErrorNotifications)this.telemetryClientComms.sendErrorOccurred(new ErrorOccurredRequest({errorTimestamp:Date.now(),errorId:notification.eventId,message:notification.summary.substring(0,500)}));this.pendingErrorNotifications.length=0}dispose(){this.telemetryService.dispose();console.log=this.originalConsole.log;console.info=this.originalConsole.info;console.warn=this.originalConsole.warn;console.error=this.originalConsole.error;console.debug=this.originalConsole.debug;if(this.originalOnError!=null)window.onerror=this.originalOnError;if(this.originalOnUnhandledRejection!=null)window.onunhandledrejection=this.originalOnUnhandledRejection;if(this.originalSetTimeout!=null)window.setTimeout=this.originalSetTimeout;if(this.originalSetInterval!=null)window.setInterval=this.originalSetInterval;if(this.originalRequestAnimationFrame!=null)window.requestAnimationFrame=this.originalRequestAnimationFrame;if(this.visibilityChangeHandler!=null)document.removeEventListener("visibilitychange",this.visibilityChangeHandler);if(this.pagehideHandler!=null)window.removeEventListener("pagehide",this.pagehideHandler);this.pendingErrorNotifications.length=0}constructor(connectToParent,createTelemetryClientComms,telemetryService){this.connectToParent=connectToParent;this.createTelemetryClientComms=createTelemetryClientComms;this.telemetryService=telemetryService;this.isInitialized=false;this.pendingErrorNotifications=[];this.originalOnUnhandledRejection=null;const originalLog=console.log.bind(console);const originalInfo=console.info.bind(console);const originalWarn=console.warn.bind(console);const originalError=console.error.bind(console);const originalDebug=console.debug.bind(console);this.originalConsole={log:originalLog,info:originalInfo,warn:originalWarn,error:originalError,debug:originalDebug};this.errorService=new CloudflareErrorService("Telemetry",this.telemetryService,this.originalConsole);this.setupReleaseContext();this.setupConsoleHandlers();this.setupGlobalErrorHandlers();this.setupBrowserApiHandlers();this.setupPageUnloadHandler()}}const fetchTelemetryService=new FetchTelemetryService;window.telemetrySdk=new TelemetrySdk(connectToParent,(comms=>new TelemetryClientComms(comms)),fetchTelemetryService);window.telemetrySdk.setupParentCommunication()})();