anchor.diff:      LargeUrl : string
     }
   
  -type Card =
  +type CustomCard =
     {
       Title : string
       Content : string
       Image : Image option
     }
   
  +type Card =
  +  | LinkAccount
  +  | Custom of CustomCard
  +
  +type Response =
  +  {
  +    EndSession : bool
  +    Speech : Speech option
  +    Reprompt : Speech option
  +    Card : Card option
  +  }
  +
   module Response =
     let private makeResponse sessionAttributes response =
       {
  
positive.code: 
  let attributesKey = "AlexaFs"
  
  [<Emit("Object.keys($0)")>]
  let objKeys obj : string[] = jsNative
  
  let parseRequest (initialAttributes : 'a) (request : Interop.Request) : Request * Session<'a> =
    let parsedRequest =
      match request.request.``type`` with
      | RequestType.LaunchRequest -> Launch
      | RequestType.IntentRequest ->
        let intent = request.request.intent.Value
        let slotKeys = objKeys intent.slots
        let slots =
          slotKeys
          |> Array.map(fun key ->
            let slot = intent.slots?(key)
            !!slot?name, !!slot?value
          )
          |> Map.ofArray
        Intent(intent.name, slots)
      | RequestType.SessionEndedRequest -> SessionEnded(request.request.reason.Value)
    let attributes = !!request.session.attributes?(attributesKey)
    let session =
      {
        Attributes = defaultArg attributes initialAttributes
        IsNewSession = request.session.``new``
        Original = request
      }
    parsedRequest, session
  
  type Speech =
    | Text of string
  
negative.code:     }
  
    let private makeCard card =
      match card with
      | LinkAccount ->
        {
          defaultCard with
            ``type`` = Interop.CardType.LinkAccount
        }
      | Custom details ->
        match details.Image with
        | None ->
          { defaultCard with
              ``type`` = Interop.CardType.Simple
              title = Some details.Title
              content = Some details.Content
          }
        | Some image ->
          {
            defaultCard with
              ``type`` = Interop.CardType.Standard
              title = Some details.Title
              text = Some details.Content
              image = Some (makeImage image)
          }
  
    let toRawResponse response attributes =
      makeResponse
        attributes
        {
          outputSpeech = response.Speech |> Option.map makeSpeech
          reprompt = response.Reprompt |> Option.map (fun reprompt -> { outputSpeech = makeSpeech reprompt })
          shouldEndSession = response.EndSession
          card = response.Card |> Option.map makeCard
        }
  
    let empty =
      {
        EndSession = false
        Speech = None
        Reprompt = None
        Card = None
      }
  
    let withSpeech speech response =
      { response with Speech = Some speech }
  
    let say speech =
      { empty with Speech = Some speech }
  
    let withReprompt speech response =
      { response with Reprompt = Some speech }
  
    let endSession response =
      { response with EndSession = true }
  
    let withCard card response =
      { response with Card = Some card }
  
    let withCustomCard card response =
      { response with Card = Some (Custom card) }
  
    let withLinkAccount response =
      { response with Card = Some LinkAccount }
  
    let linkAccount speechOption =
      { empty with Card = Some LinkAccount }
  
  let handler = createHandler (fun context request -> async {
    let request, session = Request.ofRawRequest None request
    let response =
      Response.say (Text "Hello world!")
      |> Response.withCard (
        Custom
          {
            Title = "My Card"
            Content = "Info about this skill"
            Image = Some
              {
                SmallUrl = "https://placehold.it/720x480"
                LargeUrl = "https://placehold.it/1200x800"
              }
          }
      )
      |> Response.withReprompt (SSML """<speech>Use SSML to control how a word is <w role="ivona:VBD">read</w> out.</speech>""")
      |> Response.endSession
  
    // Prompt user to log in
    let linkAccount = Response.linkAccount (Some (Text "Please log in."))
    return Response.toRawResponse response None
  })
  