kandi background
Explore Kits

kitten | The fast and fun way to write YARN applications | Continuous Deployment library

 by   cloudera Java Version: Current License: Apache-2.0

 by   cloudera Java Version: Current License: Apache-2.0

Download this library from

kandi X-RAY | kitten Summary

kitten is a Java library typically used in Devops, Continuous Deployment, Docker, Hadoop applications. kitten has no bugs, it has no vulnerabilities, it has build file available, it has a Permissive License and it has low support. You can download it from GitHub.
Kitten is a set of tools for writing and running applications on YARN, the general-purpose resource scheduling framework that ships with Hadoop 2.2.0. Kitten handles the boilerplate around configuring and launching YARN containers, allowing developers to easily deploy distributed applications that run under YARN. This link provides a useful overview of what is required to create a new YARN application, and should also help you understand the motivation for creating Kitten.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • kitten has a low active ecosystem.
  • It has 132 star(s) with 39 fork(s). There are 24 watchers for this library.
  • It had no major release in the last 12 months.
  • There are 1 open issues and 2 have been closed. On average issues are closed in 54 days. There are 1 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of kitten is current.
kitten Support
Best in #Continuous Deployment
Average in #Continuous Deployment
kitten Support
Best in #Continuous Deployment
Average in #Continuous Deployment

quality kandi Quality

  • kitten has 0 bugs and 0 code smells.
kitten Quality
Best in #Continuous Deployment
Average in #Continuous Deployment
kitten Quality
Best in #Continuous Deployment
Average in #Continuous Deployment

securitySecurity

  • kitten has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • kitten code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
kitten Security
Best in #Continuous Deployment
Average in #Continuous Deployment
kitten Security
Best in #Continuous Deployment
Average in #Continuous Deployment

license License

  • kitten is licensed under the Apache-2.0 License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
kitten License
Best in #Continuous Deployment
Average in #Continuous Deployment
kitten License
Best in #Continuous Deployment
Average in #Continuous Deployment

buildReuse

  • kitten releases are not available. You will need to build from source code and install.
  • Build file is available. You can build the component from source.
  • Installation instructions, examples and code snippets are available.
  • kitten saves you 944 person hours of effort in developing the same functionality from scratch.
  • It has 2152 lines of code, 187 functions and 30 files.
  • It has medium code complexity. Code complexity directly impacts maintainability of the code.
kitten Reuse
Best in #Continuous Deployment
Average in #Continuous Deployment
kitten Reuse
Best in #Continuous Deployment
Average in #Continuous Deployment
Top functions reviewed by kandi - BETA

kandi has reviewed kitten and discovered the below as its top functions. This is intended to give you an instant insight into kitten implemented functionality, and help decide if they suit your requirements.

  • Starts the recovery process .
    • Construct a local resource .
      • Handles the application .
        • Triggers the list of completed containers .
          • Initialize the configuration for the given container .
            • Get the number of bytes of a glob .
              • Get container launch parameters .
                • Returns the application path .
                  • Runs the application master .
                    • Creates a new container launch context .

                      Get all kandi verified functions for this library.

                      Get all kandi verified functions for this library.

                      kitten Key Features

                      The fast and fun way to write YARN applications.

                      Build and Installation

                      copy iconCopydownload iconDownload
                      mvn clean install
                      

                      Configuration Language

                      copy iconCopydownload iconDownload
                      a = { "this", "is", "a", "lua", "table" }
                      
                      b = {
                        and = "so",
                        is = "this",
                        ["a.key.with.dots"] = "is allowed using special syntax"
                      }
                      

                      The

                      copy iconCopydownload iconDownload
                      distshell = yarn {
                        name = "Distributed Shell",
                        timeout = 10000,
                        memory = 512,
                      
                        master = {
                          env = base_env, -- Defined elsewhere in the file
                          command = {
                            base = "java -Xmx128m com.cloudera.kitten.appmaster.ApplicationMaster",
                            args = { "-conf job.xml" }, -- job.xml contains the client configuration info.
                          }
                        },
                      
                        container = {
                          instances = 3,
                          env = base_env,  -- Defined elsewhere in the file
                          command = "echo 'Hello World!' >> /tmp/hello_world"
                        }
                      }
                      

                      The

                      copy iconCopydownload iconDownload
                      base = cat { x = 1, y = 2, z = 3 }  -- 'base' is a reference to a function, not a table.
                      derived = base { x = 17, y = 29 }   -- 'derived' also has the key-value pair 'z=3' defined in it as well.
                      base_as_table = base {}             -- 'base_as_table' is a table, not a function.
                      

                      HTML adding text beside an Image

                      copy iconCopydownload iconDownload
                      .image1 {
                          position: relative;
                      }
                      
                      .image1 font {
                          position: absolute;
                          bottom: 10px;
                          left: 10px;
                      }
                      

                      Static Files in express

                      copy iconCopydownload iconDownload
                      app.use(express.static('public'));  
                      
                      /my-project
                          server
                          public
                              images
                                  kitten.jpg
                      
                      app.use(express.static("/my-project/public"));
                      
                      <img src="/images/kitten.jpg">
                      
                      app.use(express.static("/my-project/public/images"));
                      
                      <img src="/kitten.jpg">
                      
                      /my-project
                          server
                          public
                              images
                                  kitten.jpg
                      
                      app.use(express.static("/my-project/public"));
                      
                      <img src="/images/kitten.jpg">
                      
                      app.use(express.static("/my-project/public/images"));
                      
                      <img src="/kitten.jpg">
                      
                      /my-project
                          server
                          public
                              images
                                  kitten.jpg
                      
                      app.use(express.static("/my-project/public"));
                      
                      <img src="/images/kitten.jpg">
                      
                      app.use(express.static("/my-project/public/images"));
                      
                      <img src="/kitten.jpg">
                      
                      /my-project
                          server
                          public
                              images
                                  kitten.jpg
                      
                      app.use(express.static("/my-project/public"));
                      
                      <img src="/images/kitten.jpg">
                      
                      app.use(express.static("/my-project/public/images"));
                      
                      <img src="/kitten.jpg">
                      
                      /my-project
                          server
                          public
                              images
                                  kitten.jpg
                      
                      app.use(express.static("/my-project/public"));
                      
                      <img src="/images/kitten.jpg">
                      
                      app.use(express.static("/my-project/public/images"));
                      
                      <img src="/kitten.jpg">
                      

                      How to remove this blue outline in iOS browsers for UI Kitten input component

                      copy iconCopydownload iconDownload
                      /* Remove outline for non-keyboard :focus */
                      *:focus:not(.focus-visible) {
                        outline: none;
                      }
                      
                      /* Optional: Customize .focus-visible */
                      .focus-visible {
                        outline-color: lightgreen;
                      }
                      

                      java.lang.NoSuchMethodError: No virtual method setSkipClientToken(Z)V in class Lcom/facebook/GraphRequest;

                      copy iconCopydownload iconDownload
                      implementation 'com.facebook.android:facebook-marketing:[4,5)'
                      
                      implementation 'com.facebook.android:facebook-marketing:latest.release'
                      
                      implementation 'com.facebook.android:facebook-marketing:[4,5)'
                      
                      implementation 'com.facebook.android:facebook-marketing:latest.release'
                      

                      Pandas sum over rows using conditional substring of other columns

                      copy iconCopydownload iconDownload
                      df0["rabbit"] = df[ [ c for c in df.columns if "rabbit" in c ] ].sum( axis = 1 )
                      
                      >>> df0.head()
                          date    rabbit    kitten       hare
                      0 2021-01-03  7.692142  1.920358  33.444147
                      1 2021-01-04  8.413968  0.999868  31.448853
                      2 2021-01-05  8.878359  1.957287  32.017930
                      3 2021-01-06  9.513102  0.838440  33.003162
                      4 2021-01-07  9.055322  0.622813  31.929664
                      
                      df0["rabbit"] = df[ [ c for c in df.columns if "rabbit" in c ] ].sum( axis = 1 )
                      
                      >>> df0.head()
                          date    rabbit    kitten       hare
                      0 2021-01-03  7.692142  1.920358  33.444147
                      1 2021-01-04  8.413968  0.999868  31.448853
                      2 2021-01-05  8.878359  1.957287  32.017930
                      3 2021-01-06  9.513102  0.838440  33.003162
                      4 2021-01-07  9.055322  0.622813  31.929664
                      
                      df1 = df.groupby([c[:4] for c in df.columns], axis=1).sum()
                      
                          date    hare        kitt        rabb
                      0   0.0     30.276673   1.076560    9.665169
                      1   0.0     31.774017   1.445791    10.263471
                      2   0.0     32.620976   1.627564    8.708358
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      sd = {s[:4]:s for s in species}
                      df[['date']].join(df1.drop(columns = 'date')).rename(columns = sd)
                      
                          date         hare       kitten      rabbit
                      0   2021-01-03  30.276673   1.076560    9.665169
                      1   2021-01-04  31.774017   1.445791    10.263471
                      2   2021-01-05  32.620976   1.627564    8.708358
                      ...
                      
                      spnames = [next(s for s in species if s in colname) for colname in df.columns[1:]]
                      df.set_index('date').groupby(spnames, axis=1).sum()
                      
                      print(spnames)
                      ['rabbit', 'rabbit', 'kitten', 'kitten', 'hare', 'hare', 'hare', 'hare']
                      
                      
                      df1 = df.groupby([c[:4] for c in df.columns], axis=1).sum()
                      
                          date    hare        kitt        rabb
                      0   0.0     30.276673   1.076560    9.665169
                      1   0.0     31.774017   1.445791    10.263471
                      2   0.0     32.620976   1.627564    8.708358
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      sd = {s[:4]:s for s in species}
                      df[['date']].join(df1.drop(columns = 'date')).rename(columns = sd)
                      
                          date         hare       kitten      rabbit
                      0   2021-01-03  30.276673   1.076560    9.665169
                      1   2021-01-04  31.774017   1.445791    10.263471
                      2   2021-01-05  32.620976   1.627564    8.708358
                      ...
                      
                      spnames = [next(s for s in species if s in colname) for colname in df.columns[1:]]
                      df.set_index('date').groupby(spnames, axis=1).sum()
                      
                      print(spnames)
                      ['rabbit', 'rabbit', 'kitten', 'kitten', 'hare', 'hare', 'hare', 'hare']
                      
                      
                      df1 = df.groupby([c[:4] for c in df.columns], axis=1).sum()
                      
                          date    hare        kitt        rabb
                      0   0.0     30.276673   1.076560    9.665169
                      1   0.0     31.774017   1.445791    10.263471
                      2   0.0     32.620976   1.627564    8.708358
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      sd = {s[:4]:s for s in species}
                      df[['date']].join(df1.drop(columns = 'date')).rename(columns = sd)
                      
                          date         hare       kitten      rabbit
                      0   2021-01-03  30.276673   1.076560    9.665169
                      1   2021-01-04  31.774017   1.445791    10.263471
                      2   2021-01-05  32.620976   1.627564    8.708358
                      ...
                      
                      spnames = [next(s for s in species if s in colname) for colname in df.columns[1:]]
                      df.set_index('date').groupby(spnames, axis=1).sum()
                      
                      print(spnames)
                      ['rabbit', 'rabbit', 'kitten', 'kitten', 'hare', 'hare', 'hare', 'hare']
                      
                      
                      df1 = df.groupby([c[:4] for c in df.columns], axis=1).sum()
                      
                          date    hare        kitt        rabb
                      0   0.0     30.276673   1.076560    9.665169
                      1   0.0     31.774017   1.445791    10.263471
                      2   0.0     32.620976   1.627564    8.708358
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      sd = {s[:4]:s for s in species}
                      df[['date']].join(df1.drop(columns = 'date')).rename(columns = sd)
                      
                          date         hare       kitten      rabbit
                      0   2021-01-03  30.276673   1.076560    9.665169
                      1   2021-01-04  31.774017   1.445791    10.263471
                      2   2021-01-05  32.620976   1.627564    8.708358
                      ...
                      
                      spnames = [next(s for s in species if s in colname) for colname in df.columns[1:]]
                      df.set_index('date').groupby(spnames, axis=1).sum()
                      
                      print(spnames)
                      ['rabbit', 'rabbit', 'kitten', 'kitten', 'hare', 'hare', 'hare', 'hare']
                      
                      
                      df1 = df.groupby([c[:4] for c in df.columns], axis=1).sum()
                      
                          date    hare        kitt        rabb
                      0   0.0     30.276673   1.076560    9.665169
                      1   0.0     31.774017   1.445791    10.263471
                      2   0.0     32.620976   1.627564    8.708358
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      sd = {s[:4]:s for s in species}
                      df[['date']].join(df1.drop(columns = 'date')).rename(columns = sd)
                      
                          date         hare       kitten      rabbit
                      0   2021-01-03  30.276673   1.076560    9.665169
                      1   2021-01-04  31.774017   1.445791    10.263471
                      2   2021-01-05  32.620976   1.627564    8.708358
                      ...
                      
                      spnames = [next(s for s in species if s in colname) for colname in df.columns[1:]]
                      df.set_index('date').groupby(spnames, axis=1).sum()
                      
                      print(spnames)
                      ['rabbit', 'rabbit', 'kitten', 'kitten', 'hare', 'hare', 'hare', 'hare']
                      
                      
                      df1 = df.groupby([c[:4] for c in df.columns], axis=1).sum()
                      
                          date    hare        kitt        rabb
                      0   0.0     30.276673   1.076560    9.665169
                      1   0.0     31.774017   1.445791    10.263471
                      2   0.0     32.620976   1.627564    8.708358
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      sd = {s[:4]:s for s in species}
                      df[['date']].join(df1.drop(columns = 'date')).rename(columns = sd)
                      
                          date         hare       kitten      rabbit
                      0   2021-01-03  30.276673   1.076560    9.665169
                      1   2021-01-04  31.774017   1.445791    10.263471
                      2   2021-01-05  32.620976   1.627564    8.708358
                      ...
                      
                      spnames = [next(s for s in species if s in colname) for colname in df.columns[1:]]
                      df.set_index('date').groupby(spnames, axis=1).sum()
                      
                      print(spnames)
                      ['rabbit', 'rabbit', 'kitten', 'kitten', 'hare', 'hare', 'hare', 'hare']
                      
                      
                      df = df.set_index('date')
                      df.columns = df.columns.str.split('([a-z]+)(\d+)', expand=True)
                      df = df.droplevel([0,2], axis=1).stack().groupby(level=0).sum().reset_index()
                      
                               date       hare    kitten     rabbit
                      0  2021-01-03  31.705293  0.901572   9.816273
                      1  2021-01-04  28.816726  0.551446   9.305995
                      2  2021-01-05  29.331354  1.198637   9.346137
                      3  2021-01-06  31.019732  0.714525   8.316858
                      4  2021-01-07  30.554802  1.134589   8.487755
                      ...
                      
                      df = df.set_index('date')
                      df.columns = df.columns.str.split('([a-z]+)(\d+)', expand=True)
                      df = df.droplevel([0,2], axis=1).stack().groupby(level=0).sum().reset_index()
                      
                               date       hare    kitten     rabbit
                      0  2021-01-03  31.705293  0.901572   9.816273
                      1  2021-01-04  28.816726  0.551446   9.305995
                      2  2021-01-05  29.331354  1.198637   9.346137
                      3  2021-01-06  31.019732  0.714525   8.316858
                      4  2021-01-07  30.554802  1.134589   8.487755
                      ...
                      
                      species = ['rabbit', 'kitten', 'hare']
                      
                      #Rename df columns to allow use of pd.wide_to_long
                      
                      df.columns =df.columns.str.replace('\_\w+$','', regex=True)
                      
                      new=(df0.set_index('date')#Set date as index
                            .join(
                                pd.wide_to_long(df, species, i="date", j="suffix").droplevel(level=1)#Melt columns into each of the element in the list and sum
                                .groupby('date').sum()#Do summation by date
                            )
                                
                            )
                      

                      queries on users' comments in MongoDB

                      copy iconCopydownload iconDownload
                         db.collection.aggregate([
                         {
                           $unwind: "$comments"
                         },
                          {
                           $project: {
                           _id: 0,
                           items: {
                             $filter: {
                              input: "$comments.replies",
                              as: "item",
                               cond: {
                                $eq: [
                                "$$item.user",
                                "$comments.user"
                              ]
                             }
                            }
                           }
                          }
                          },
                          {
                             $unwind: "$items"
                           },
                            {
                            $project: {
                            "self_repling_user": "$items.user",
                            "self_repling_comment": "$items.text"
                            }
                           }
                         ])
                      
                      db.collection.aggregate([
                         {
                         $unwind: "$comments"
                         },
                         {
                          $unwind: "$comments.replies"
                         },
                         {
                          $group: {
                          _id: "allusers",
                          "user2": {
                            $push: "$comments.user"
                             },
                            user1: {
                              $push: "$comments.replies.user"
                             }
                            }
                         },
                          {
                           $project: {
                               users: {
                                 $concatArrays: [
                                   "$user1",
                                  "$user2"
                                ]
                              }
                            }
                          },
                          {
                           $unwind: "$users"
                          },
                          {
                            $group: {
                             _id: "$users",
                            count: {
                             $sum: 1
                             }
                            }
                          },
                          {
                           $match: {
                           count: {
                             $gt: 1
                           }
                          }
                        }
                        ])
                      
                         db.collection.aggregate([
                         {
                           $unwind: "$comments"
                         },
                          {
                           $project: {
                           _id: 0,
                           items: {
                             $filter: {
                              input: "$comments.replies",
                              as: "item",
                               cond: {
                                $eq: [
                                "$$item.user",
                                "$comments.user"
                              ]
                             }
                            }
                           }
                          }
                          },
                          {
                             $unwind: "$items"
                           },
                            {
                            $project: {
                            "self_repling_user": "$items.user",
                            "self_repling_comment": "$items.text"
                            }
                           }
                         ])
                      
                      db.collection.aggregate([
                         {
                         $unwind: "$comments"
                         },
                         {
                          $unwind: "$comments.replies"
                         },
                         {
                          $group: {
                          _id: "allusers",
                          "user2": {
                            $push: "$comments.user"
                             },
                            user1: {
                              $push: "$comments.replies.user"
                             }
                            }
                         },
                          {
                           $project: {
                               users: {
                                 $concatArrays: [
                                   "$user1",
                                  "$user2"
                                ]
                              }
                            }
                          },
                          {
                           $unwind: "$users"
                          },
                          {
                            $group: {
                             _id: "$users",
                            count: {
                             $sum: 1
                             }
                            }
                          },
                          {
                           $match: {
                           count: {
                             $gt: 1
                           }
                          }
                        }
                        ])
                      
                      var r = [
                          // target                                                                                                               
                          {"_id": "P1", from:"OP", text: "orig", ts:new ISODate("2020-01-01")}
                            // level 0                                                                                                            
                            ,{"_id": "P2", from:"A", ref:"P1", text: "not bad", ts:new ISODate("2020-01-01")}
                            ,{"_id": "P3", from:"B", ref:"P1", text: "corn", ts:new ISODate("2020-01-01")}
                            // level 1                                                                                                          
                              ,{"_id": "P4", from:"C", ref:"P3", text: "maybe", ts:new ISODate("2020-01-02")}
                                // level 2                                                                                                        
                                ,{"_id": "P41", from:"D", ref:"P4", text: "hoo", ts:new ISODate("2020-01-08")}
                                  // level 3                                                                                                      
                                  ,{"_id": "P61", from:"A", ref:"P41", text: "concerned", ts:new ISODate("2020-01-02")}
                      
                              ,{"_id": "P42", from:"E", ref:"P3", text: "hello", ts:new ISODate("2020-01-02")}
                      
                      
                          ,{"_id": "P5", from:"OP2", text: "orig2",         ts:new ISODate("2020-01-01")}
                          ,{"_id": "P6", from:"C", ref:"P5", text: "another thing...", ts:new ISODate("2020-01-06")}
                      ];
                      
                      db.foo.aggregate([
                          {$match: {"_id": "P1"}},
                          {$graphLookup: {
                              from: "foo",
                              connectToField: "ref",
                              connectFromField: "_id",
                              startWith: "$_id", // usually value of connectFromField                                                             
                              depthField: "n",
                              as: "zz"
                          }}
                      ]);
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : [
                              {
                                  "_id" : "P42",
                                  "from" : "E",
                                  "ref" : "P3",
                                  "text" : "hello",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P4",
                                  "from" : "C",
                                  "ref" : "P3",
                                  "text" : "maybe",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                              {
                                  "_id" : "P41",
                                  "from" : "D",
                                  "ref" : "P4",
                                  "text" : "hoo",
                                  "ts" : ISODate("2020-01-08T00:00:00Z"),
                                  "n" : NumberLong(2)
                              },
                              {
                                  "_id" : "P61",
                                  "from" : "A",
                                  "ref" : "P41",
                                  "text" : "concerned",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(3)
                              },
                              {
                                  "_id" : "P3",
                                  "from" : "B",
                                  "ref" : "P1",
                                  "text" : "corn",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              }
                          ]
                      }
                      
                          ,{$addFields: {zz: {$slice: [ {$filter: {
                                                          input: "$zz",
                                                          cond:  {$eq:[0,"$$this.n"]}
                                                        }}, 0, 2] }
                          }}
                      
                      ,{$addFields: {zz: {$reduce: {
                              input: "$zz",
                              initialValue: {ts:new ISODate("2000-01-01")}, // init to a REALLY old date                                    
                                  in: {$cond: [
                                      {$gt:["$$this.ts","$$value.ts"]}, // if higher than prev
                                      "$$this",  // then use this one
                                      "$$value"  // else keep highest seen so far
                                      ]}
                              }}
                          }}
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : {
                              "_id" : "P41",
                              "from" : "D",
                              "ref" : "P4",
                              "text" : "hoo",
                              "ts" : ISODate("2020-01-08T00:00:00Z"),
                              "n" : NumberLong(2)
                          }
                      }
                      
                          ,{$project: {zz: {$concatArrays: [
                                             // Make array of 1.  Call n -1 to identify it as the
                                             // initial target doc:
                                             [{_id: "$_id",n:-1,from:"$from",text:"$text",ts:"$ts"}], // make array of 1
                                              "$zz"
                                             ]}
                          }}
                      
                      {
                          "_id" : "P1",
                          "zz" : [
                              {
                                  "_id" : "P1",
                                  "n" : -1,
                                  "from" : "OP",
                                  "text" : "orig",
                                  "ts" : ISODate("2020-01-01T00:00:00Z")
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                      ....
                      
                      var r = [
                          // target                                                                                                               
                          {"_id": "P1", from:"OP", text: "orig", ts:new ISODate("2020-01-01")}
                            // level 0                                                                                                            
                            ,{"_id": "P2", from:"A", ref:"P1", text: "not bad", ts:new ISODate("2020-01-01")}
                            ,{"_id": "P3", from:"B", ref:"P1", text: "corn", ts:new ISODate("2020-01-01")}
                            // level 1                                                                                                          
                              ,{"_id": "P4", from:"C", ref:"P3", text: "maybe", ts:new ISODate("2020-01-02")}
                                // level 2                                                                                                        
                                ,{"_id": "P41", from:"D", ref:"P4", text: "hoo", ts:new ISODate("2020-01-08")}
                                  // level 3                                                                                                      
                                  ,{"_id": "P61", from:"A", ref:"P41", text: "concerned", ts:new ISODate("2020-01-02")}
                      
                              ,{"_id": "P42", from:"E", ref:"P3", text: "hello", ts:new ISODate("2020-01-02")}
                      
                      
                          ,{"_id": "P5", from:"OP2", text: "orig2",         ts:new ISODate("2020-01-01")}
                          ,{"_id": "P6", from:"C", ref:"P5", text: "another thing...", ts:new ISODate("2020-01-06")}
                      ];
                      
                      db.foo.aggregate([
                          {$match: {"_id": "P1"}},
                          {$graphLookup: {
                              from: "foo",
                              connectToField: "ref",
                              connectFromField: "_id",
                              startWith: "$_id", // usually value of connectFromField                                                             
                              depthField: "n",
                              as: "zz"
                          }}
                      ]);
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : [
                              {
                                  "_id" : "P42",
                                  "from" : "E",
                                  "ref" : "P3",
                                  "text" : "hello",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P4",
                                  "from" : "C",
                                  "ref" : "P3",
                                  "text" : "maybe",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                              {
                                  "_id" : "P41",
                                  "from" : "D",
                                  "ref" : "P4",
                                  "text" : "hoo",
                                  "ts" : ISODate("2020-01-08T00:00:00Z"),
                                  "n" : NumberLong(2)
                              },
                              {
                                  "_id" : "P61",
                                  "from" : "A",
                                  "ref" : "P41",
                                  "text" : "concerned",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(3)
                              },
                              {
                                  "_id" : "P3",
                                  "from" : "B",
                                  "ref" : "P1",
                                  "text" : "corn",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              }
                          ]
                      }
                      
                          ,{$addFields: {zz: {$slice: [ {$filter: {
                                                          input: "$zz",
                                                          cond:  {$eq:[0,"$$this.n"]}
                                                        }}, 0, 2] }
                          }}
                      
                      ,{$addFields: {zz: {$reduce: {
                              input: "$zz",
                              initialValue: {ts:new ISODate("2000-01-01")}, // init to a REALLY old date                                    
                                  in: {$cond: [
                                      {$gt:["$$this.ts","$$value.ts"]}, // if higher than prev
                                      "$$this",  // then use this one
                                      "$$value"  // else keep highest seen so far
                                      ]}
                              }}
                          }}
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : {
                              "_id" : "P41",
                              "from" : "D",
                              "ref" : "P4",
                              "text" : "hoo",
                              "ts" : ISODate("2020-01-08T00:00:00Z"),
                              "n" : NumberLong(2)
                          }
                      }
                      
                          ,{$project: {zz: {$concatArrays: [
                                             // Make array of 1.  Call n -1 to identify it as the
                                             // initial target doc:
                                             [{_id: "$_id",n:-1,from:"$from",text:"$text",ts:"$ts"}], // make array of 1
                                              "$zz"
                                             ]}
                          }}
                      
                      {
                          "_id" : "P1",
                          "zz" : [
                              {
                                  "_id" : "P1",
                                  "n" : -1,
                                  "from" : "OP",
                                  "text" : "orig",
                                  "ts" : ISODate("2020-01-01T00:00:00Z")
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                      ....
                      
                      var r = [
                          // target                                                                                                               
                          {"_id": "P1", from:"OP", text: "orig", ts:new ISODate("2020-01-01")}
                            // level 0                                                                                                            
                            ,{"_id": "P2", from:"A", ref:"P1", text: "not bad", ts:new ISODate("2020-01-01")}
                            ,{"_id": "P3", from:"B", ref:"P1", text: "corn", ts:new ISODate("2020-01-01")}
                            // level 1                                                                                                          
                              ,{"_id": "P4", from:"C", ref:"P3", text: "maybe", ts:new ISODate("2020-01-02")}
                                // level 2                                                                                                        
                                ,{"_id": "P41", from:"D", ref:"P4", text: "hoo", ts:new ISODate("2020-01-08")}
                                  // level 3                                                                                                      
                                  ,{"_id": "P61", from:"A", ref:"P41", text: "concerned", ts:new ISODate("2020-01-02")}
                      
                              ,{"_id": "P42", from:"E", ref:"P3", text: "hello", ts:new ISODate("2020-01-02")}
                      
                      
                          ,{"_id": "P5", from:"OP2", text: "orig2",         ts:new ISODate("2020-01-01")}
                          ,{"_id": "P6", from:"C", ref:"P5", text: "another thing...", ts:new ISODate("2020-01-06")}
                      ];
                      
                      db.foo.aggregate([
                          {$match: {"_id": "P1"}},
                          {$graphLookup: {
                              from: "foo",
                              connectToField: "ref",
                              connectFromField: "_id",
                              startWith: "$_id", // usually value of connectFromField                                                             
                              depthField: "n",
                              as: "zz"
                          }}
                      ]);
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : [
                              {
                                  "_id" : "P42",
                                  "from" : "E",
                                  "ref" : "P3",
                                  "text" : "hello",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P4",
                                  "from" : "C",
                                  "ref" : "P3",
                                  "text" : "maybe",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                              {
                                  "_id" : "P41",
                                  "from" : "D",
                                  "ref" : "P4",
                                  "text" : "hoo",
                                  "ts" : ISODate("2020-01-08T00:00:00Z"),
                                  "n" : NumberLong(2)
                              },
                              {
                                  "_id" : "P61",
                                  "from" : "A",
                                  "ref" : "P41",
                                  "text" : "concerned",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(3)
                              },
                              {
                                  "_id" : "P3",
                                  "from" : "B",
                                  "ref" : "P1",
                                  "text" : "corn",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              }
                          ]
                      }
                      
                          ,{$addFields: {zz: {$slice: [ {$filter: {
                                                          input: "$zz",
                                                          cond:  {$eq:[0,"$$this.n"]}
                                                        }}, 0, 2] }
                          }}
                      
                      ,{$addFields: {zz: {$reduce: {
                              input: "$zz",
                              initialValue: {ts:new ISODate("2000-01-01")}, // init to a REALLY old date                                    
                                  in: {$cond: [
                                      {$gt:["$$this.ts","$$value.ts"]}, // if higher than prev
                                      "$$this",  // then use this one
                                      "$$value"  // else keep highest seen so far
                                      ]}
                              }}
                          }}
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : {
                              "_id" : "P41",
                              "from" : "D",
                              "ref" : "P4",
                              "text" : "hoo",
                              "ts" : ISODate("2020-01-08T00:00:00Z"),
                              "n" : NumberLong(2)
                          }
                      }
                      
                          ,{$project: {zz: {$concatArrays: [
                                             // Make array of 1.  Call n -1 to identify it as the
                                             // initial target doc:
                                             [{_id: "$_id",n:-1,from:"$from",text:"$text",ts:"$ts"}], // make array of 1
                                              "$zz"
                                             ]}
                          }}
                      
                      {
                          "_id" : "P1",
                          "zz" : [
                              {
                                  "_id" : "P1",
                                  "n" : -1,
                                  "from" : "OP",
                                  "text" : "orig",
                                  "ts" : ISODate("2020-01-01T00:00:00Z")
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                      ....
                      
                      var r = [
                          // target                                                                                                               
                          {"_id": "P1", from:"OP", text: "orig", ts:new ISODate("2020-01-01")}
                            // level 0                                                                                                            
                            ,{"_id": "P2", from:"A", ref:"P1", text: "not bad", ts:new ISODate("2020-01-01")}
                            ,{"_id": "P3", from:"B", ref:"P1", text: "corn", ts:new ISODate("2020-01-01")}
                            // level 1                                                                                                          
                              ,{"_id": "P4", from:"C", ref:"P3", text: "maybe", ts:new ISODate("2020-01-02")}
                                // level 2                                                                                                        
                                ,{"_id": "P41", from:"D", ref:"P4", text: "hoo", ts:new ISODate("2020-01-08")}
                                  // level 3                                                                                                      
                                  ,{"_id": "P61", from:"A", ref:"P41", text: "concerned", ts:new ISODate("2020-01-02")}
                      
                              ,{"_id": "P42", from:"E", ref:"P3", text: "hello", ts:new ISODate("2020-01-02")}
                      
                      
                          ,{"_id": "P5", from:"OP2", text: "orig2",         ts:new ISODate("2020-01-01")}
                          ,{"_id": "P6", from:"C", ref:"P5", text: "another thing...", ts:new ISODate("2020-01-06")}
                      ];
                      
                      db.foo.aggregate([
                          {$match: {"_id": "P1"}},
                          {$graphLookup: {
                              from: "foo",
                              connectToField: "ref",
                              connectFromField: "_id",
                              startWith: "$_id", // usually value of connectFromField                                                             
                              depthField: "n",
                              as: "zz"
                          }}
                      ]);
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : [
                              {
                                  "_id" : "P42",
                                  "from" : "E",
                                  "ref" : "P3",
                                  "text" : "hello",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P4",
                                  "from" : "C",
                                  "ref" : "P3",
                                  "text" : "maybe",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                              {
                                  "_id" : "P41",
                                  "from" : "D",
                                  "ref" : "P4",
                                  "text" : "hoo",
                                  "ts" : ISODate("2020-01-08T00:00:00Z"),
                                  "n" : NumberLong(2)
                              },
                              {
                                  "_id" : "P61",
                                  "from" : "A",
                                  "ref" : "P41",
                                  "text" : "concerned",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(3)
                              },
                              {
                                  "_id" : "P3",
                                  "from" : "B",
                                  "ref" : "P1",
                                  "text" : "corn",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              }
                          ]
                      }
                      
                          ,{$addFields: {zz: {$slice: [ {$filter: {
                                                          input: "$zz",
                                                          cond:  {$eq:[0,"$$this.n"]}
                                                        }}, 0, 2] }
                          }}
                      
                      ,{$addFields: {zz: {$reduce: {
                              input: "$zz",
                              initialValue: {ts:new ISODate("2000-01-01")}, // init to a REALLY old date                                    
                                  in: {$cond: [
                                      {$gt:["$$this.ts","$$value.ts"]}, // if higher than prev
                                      "$$this",  // then use this one
                                      "$$value"  // else keep highest seen so far
                                      ]}
                              }}
                          }}
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : {
                              "_id" : "P41",
                              "from" : "D",
                              "ref" : "P4",
                              "text" : "hoo",
                              "ts" : ISODate("2020-01-08T00:00:00Z"),
                              "n" : NumberLong(2)
                          }
                      }
                      
                          ,{$project: {zz: {$concatArrays: [
                                             // Make array of 1.  Call n -1 to identify it as the
                                             // initial target doc:
                                             [{_id: "$_id",n:-1,from:"$from",text:"$text",ts:"$ts"}], // make array of 1
                                              "$zz"
                                             ]}
                          }}
                      
                      {
                          "_id" : "P1",
                          "zz" : [
                              {
                                  "_id" : "P1",
                                  "n" : -1,
                                  "from" : "OP",
                                  "text" : "orig",
                                  "ts" : ISODate("2020-01-01T00:00:00Z")
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                      ....
                      
                      var r = [
                          // target                                                                                                               
                          {"_id": "P1", from:"OP", text: "orig", ts:new ISODate("2020-01-01")}
                            // level 0                                                                                                            
                            ,{"_id": "P2", from:"A", ref:"P1", text: "not bad", ts:new ISODate("2020-01-01")}
                            ,{"_id": "P3", from:"B", ref:"P1", text: "corn", ts:new ISODate("2020-01-01")}
                            // level 1                                                                                                          
                              ,{"_id": "P4", from:"C", ref:"P3", text: "maybe", ts:new ISODate("2020-01-02")}
                                // level 2                                                                                                        
                                ,{"_id": "P41", from:"D", ref:"P4", text: "hoo", ts:new ISODate("2020-01-08")}
                                  // level 3                                                                                                      
                                  ,{"_id": "P61", from:"A", ref:"P41", text: "concerned", ts:new ISODate("2020-01-02")}
                      
                              ,{"_id": "P42", from:"E", ref:"P3", text: "hello", ts:new ISODate("2020-01-02")}
                      
                      
                          ,{"_id": "P5", from:"OP2", text: "orig2",         ts:new ISODate("2020-01-01")}
                          ,{"_id": "P6", from:"C", ref:"P5", text: "another thing...", ts:new ISODate("2020-01-06")}
                      ];
                      
                      db.foo.aggregate([
                          {$match: {"_id": "P1"}},
                          {$graphLookup: {
                              from: "foo",
                              connectToField: "ref",
                              connectFromField: "_id",
                              startWith: "$_id", // usually value of connectFromField                                                             
                              depthField: "n",
                              as: "zz"
                          }}
                      ]);
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : [
                              {
                                  "_id" : "P42",
                                  "from" : "E",
                                  "ref" : "P3",
                                  "text" : "hello",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P4",
                                  "from" : "C",
                                  "ref" : "P3",
                                  "text" : "maybe",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                              {
                                  "_id" : "P41",
                                  "from" : "D",
                                  "ref" : "P4",
                                  "text" : "hoo",
                                  "ts" : ISODate("2020-01-08T00:00:00Z"),
                                  "n" : NumberLong(2)
                              },
                              {
                                  "_id" : "P61",
                                  "from" : "A",
                                  "ref" : "P41",
                                  "text" : "concerned",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(3)
                              },
                              {
                                  "_id" : "P3",
                                  "from" : "B",
                                  "ref" : "P1",
                                  "text" : "corn",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              }
                          ]
                      }
                      
                          ,{$addFields: {zz: {$slice: [ {$filter: {
                                                          input: "$zz",
                                                          cond:  {$eq:[0,"$$this.n"]}
                                                        }}, 0, 2] }
                          }}
                      
                      ,{$addFields: {zz: {$reduce: {
                              input: "$zz",
                              initialValue: {ts:new ISODate("2000-01-01")}, // init to a REALLY old date                                    
                                  in: {$cond: [
                                      {$gt:["$$this.ts","$$value.ts"]}, // if higher than prev
                                      "$$this",  // then use this one
                                      "$$value"  // else keep highest seen so far
                                      ]}
                              }}
                          }}
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : {
                              "_id" : "P41",
                              "from" : "D",
                              "ref" : "P4",
                              "text" : "hoo",
                              "ts" : ISODate("2020-01-08T00:00:00Z"),
                              "n" : NumberLong(2)
                          }
                      }
                      
                          ,{$project: {zz: {$concatArrays: [
                                             // Make array of 1.  Call n -1 to identify it as the
                                             // initial target doc:
                                             [{_id: "$_id",n:-1,from:"$from",text:"$text",ts:"$ts"}], // make array of 1
                                              "$zz"
                                             ]}
                          }}
                      
                      {
                          "_id" : "P1",
                          "zz" : [
                              {
                                  "_id" : "P1",
                                  "n" : -1,
                                  "from" : "OP",
                                  "text" : "orig",
                                  "ts" : ISODate("2020-01-01T00:00:00Z")
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                      ....
                      
                      var r = [
                          // target                                                                                                               
                          {"_id": "P1", from:"OP", text: "orig", ts:new ISODate("2020-01-01")}
                            // level 0                                                                                                            
                            ,{"_id": "P2", from:"A", ref:"P1", text: "not bad", ts:new ISODate("2020-01-01")}
                            ,{"_id": "P3", from:"B", ref:"P1", text: "corn", ts:new ISODate("2020-01-01")}
                            // level 1                                                                                                          
                              ,{"_id": "P4", from:"C", ref:"P3", text: "maybe", ts:new ISODate("2020-01-02")}
                                // level 2                                                                                                        
                                ,{"_id": "P41", from:"D", ref:"P4", text: "hoo", ts:new ISODate("2020-01-08")}
                                  // level 3                                                                                                      
                                  ,{"_id": "P61", from:"A", ref:"P41", text: "concerned", ts:new ISODate("2020-01-02")}
                      
                              ,{"_id": "P42", from:"E", ref:"P3", text: "hello", ts:new ISODate("2020-01-02")}
                      
                      
                          ,{"_id": "P5", from:"OP2", text: "orig2",         ts:new ISODate("2020-01-01")}
                          ,{"_id": "P6", from:"C", ref:"P5", text: "another thing...", ts:new ISODate("2020-01-06")}
                      ];
                      
                      db.foo.aggregate([
                          {$match: {"_id": "P1"}},
                          {$graphLookup: {
                              from: "foo",
                              connectToField: "ref",
                              connectFromField: "_id",
                              startWith: "$_id", // usually value of connectFromField                                                             
                              depthField: "n",
                              as: "zz"
                          }}
                      ]);
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : [
                              {
                                  "_id" : "P42",
                                  "from" : "E",
                                  "ref" : "P3",
                                  "text" : "hello",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P4",
                                  "from" : "C",
                                  "ref" : "P3",
                                  "text" : "maybe",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(1)
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                              {
                                  "_id" : "P41",
                                  "from" : "D",
                                  "ref" : "P4",
                                  "text" : "hoo",
                                  "ts" : ISODate("2020-01-08T00:00:00Z"),
                                  "n" : NumberLong(2)
                              },
                              {
                                  "_id" : "P61",
                                  "from" : "A",
                                  "ref" : "P41",
                                  "text" : "concerned",
                                  "ts" : ISODate("2020-01-02T00:00:00Z"),
                                  "n" : NumberLong(3)
                              },
                              {
                                  "_id" : "P3",
                                  "from" : "B",
                                  "ref" : "P1",
                                  "text" : "corn",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              }
                          ]
                      }
                      
                          ,{$addFields: {zz: {$slice: [ {$filter: {
                                                          input: "$zz",
                                                          cond:  {$eq:[0,"$$this.n"]}
                                                        }}, 0, 2] }
                          }}
                      
                      ,{$addFields: {zz: {$reduce: {
                              input: "$zz",
                              initialValue: {ts:new ISODate("2000-01-01")}, // init to a REALLY old date                                    
                                  in: {$cond: [
                                      {$gt:["$$this.ts","$$value.ts"]}, // if higher than prev
                                      "$$this",  // then use this one
                                      "$$value"  // else keep highest seen so far
                                      ]}
                              }}
                          }}
                      
                      {
                          "_id" : "P1",
                          "from" : "OP",
                          "text" : "orig",
                          "ts" : ISODate("2020-01-01T00:00:00Z"),
                          "zz" : {
                              "_id" : "P41",
                              "from" : "D",
                              "ref" : "P4",
                              "text" : "hoo",
                              "ts" : ISODate("2020-01-08T00:00:00Z"),
                              "n" : NumberLong(2)
                          }
                      }
                      
                          ,{$project: {zz: {$concatArrays: [
                                             // Make array of 1.  Call n -1 to identify it as the
                                             // initial target doc:
                                             [{_id: "$_id",n:-1,from:"$from",text:"$text",ts:"$ts"}], // make array of 1
                                              "$zz"
                                             ]}
                          }}
                      
                      {
                          "_id" : "P1",
                          "zz" : [
                              {
                                  "_id" : "P1",
                                  "n" : -1,
                                  "from" : "OP",
                                  "text" : "orig",
                                  "ts" : ISODate("2020-01-01T00:00:00Z")
                              },
                              {
                                  "_id" : "P2",
                                  "from" : "A",
                                  "ref" : "P1",
                                  "text" : "not bad",
                                  "ts" : ISODate("2020-01-01T00:00:00Z"),
                                  "n" : NumberLong(0)
                              },
                      ....
                      

                      How to search through a directory and find corresponding video and xml files and rename?

                      copy iconCopydownload iconDownload
                      import os
                      
                      previous_renames = {}
                      i = 1
                      for filename in os.listdir("."):
                          namepart = os.path.splitext(filename)[0]
                          ext = os.path.splitext(filename)[1]
                          if namepart in previous_renames:
                              new_name = previous_renames[namepart]
                          else:
                              new_name = f"video{i}"
                              previous_renames[namepart] = new_name
                              i += 1
                          os.rename(filename, f"{new_name}{ext}")
                      

                      R - If column contains a string from vector, append flag into another column

                      copy iconCopydownload iconDownload
                      df %>%  
                        transmute(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) 
                      
                        new_colonetext new_colcop new_coltext3
                        <list>         <list>     <list>      
                      1 <chr [1]>      <NULL>     <chr [2]>   
                      2 <chr [2]>      <chr [2]>  <NULL>      
                      3 <chr [2]>      <chr [4]>  <chr [5]>  
                      
                      myvec <- c("cat", "dog", "bird")
                      
                      pattern <- paste(myvec, collapse="|")
                      
                      library(dplyr)
                      library(tidyr)
                      df %>% 
                        mutate(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) %>% 
                        unite(topic, starts_with('new'), na.rm = TRUE, sep = ',')
                      
                          id onetext                cop                                                                        text3                                                                              topic                                     
                        <dbl> <chr>                  <chr>                                                                      <chr>                                                                              <chr>                                     
                      1     1 cat furry pink british Little Grey Cat is the nickname given to a kitten of the British Shorthai~ On October 4th the first single topic blog devoted to the little grey cat was lau~ "cat,NULL,c(\"cat\", \"cat\")"            
                      2     2 dog cat fight          Dogs have soft fur and tails so do cats Do cats like to chase their tails  there are many fights going on and this is just an example text                    "c(\"dog\", \"cat\"),c(\"cat\", \"cat\"),~
                      3     3 bird cat issues        A cat and bird can coexist in a home but you will have to take certain me~ Some cats will not care about a pet bird at all while others will make it its lif~ "c(\"bird\", \"cat\"),c(\"cat\", \"bird\"~                                                                                    
                      
                      df %>%  
                        transmute(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) 
                      
                        new_colonetext new_colcop new_coltext3
                        <list>         <list>     <list>      
                      1 <chr [1]>      <NULL>     <chr [2]>   
                      2 <chr [2]>      <chr [2]>  <NULL>      
                      3 <chr [2]>      <chr [4]>  <chr [5]>  
                      
                      myvec <- c("cat", "dog", "bird")
                      
                      pattern <- paste(myvec, collapse="|")
                      
                      library(dplyr)
                      library(tidyr)
                      df %>% 
                        mutate(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) %>% 
                        unite(topic, starts_with('new'), na.rm = TRUE, sep = ',')
                      
                          id onetext                cop                                                                        text3                                                                              topic                                     
                        <dbl> <chr>                  <chr>                                                                      <chr>                                                                              <chr>                                     
                      1     1 cat furry pink british Little Grey Cat is the nickname given to a kitten of the British Shorthai~ On October 4th the first single topic blog devoted to the little grey cat was lau~ "cat,NULL,c(\"cat\", \"cat\")"            
                      2     2 dog cat fight          Dogs have soft fur and tails so do cats Do cats like to chase their tails  there are many fights going on and this is just an example text                    "c(\"dog\", \"cat\"),c(\"cat\", \"cat\"),~
                      3     3 bird cat issues        A cat and bird can coexist in a home but you will have to take certain me~ Some cats will not care about a pet bird at all while others will make it its lif~ "c(\"bird\", \"cat\"),c(\"cat\", \"bird\"~                                                                                    
                      
                      df %>%  
                        transmute(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) 
                      
                        new_colonetext new_colcop new_coltext3
                        <list>         <list>     <list>      
                      1 <chr [1]>      <NULL>     <chr [2]>   
                      2 <chr [2]>      <chr [2]>  <NULL>      
                      3 <chr [2]>      <chr [4]>  <chr [5]>  
                      
                      myvec <- c("cat", "dog", "bird")
                      
                      pattern <- paste(myvec, collapse="|")
                      
                      library(dplyr)
                      library(tidyr)
                      df %>% 
                        mutate(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) %>% 
                        unite(topic, starts_with('new'), na.rm = TRUE, sep = ',')
                      
                          id onetext                cop                                                                        text3                                                                              topic                                     
                        <dbl> <chr>                  <chr>                                                                      <chr>                                                                              <chr>                                     
                      1     1 cat furry pink british Little Grey Cat is the nickname given to a kitten of the British Shorthai~ On October 4th the first single topic blog devoted to the little grey cat was lau~ "cat,NULL,c(\"cat\", \"cat\")"            
                      2     2 dog cat fight          Dogs have soft fur and tails so do cats Do cats like to chase their tails  there are many fights going on and this is just an example text                    "c(\"dog\", \"cat\"),c(\"cat\", \"cat\"),~
                      3     3 bird cat issues        A cat and bird can coexist in a home but you will have to take certain me~ Some cats will not care about a pet bird at all while others will make it its lif~ "c(\"bird\", \"cat\"),c(\"cat\", \"bird\"~                                                                                    
                      
                      df %>%  
                        transmute(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) 
                      
                        new_colonetext new_colcop new_coltext3
                        <list>         <list>     <list>      
                      1 <chr [1]>      <NULL>     <chr [2]>   
                      2 <chr [2]>      <chr [2]>  <NULL>      
                      3 <chr [2]>      <chr [4]>  <chr [5]>  
                      
                      myvec <- c("cat", "dog", "bird")
                      
                      pattern <- paste(myvec, collapse="|")
                      
                      library(dplyr)
                      library(tidyr)
                      df %>% 
                        mutate(across(-id, ~case_when(str_detect(., pattern) ~ str_extract_all(., pattern)), .names = "new_col{col}")) %>% 
                        unite(topic, starts_with('new'), na.rm = TRUE, sep = ',')
                      
                          id onetext                cop                                                                        text3                                                                              topic                                     
                        <dbl> <chr>                  <chr>                                                                      <chr>                                                                              <chr>                                     
                      1     1 cat furry pink british Little Grey Cat is the nickname given to a kitten of the British Shorthai~ On October 4th the first single topic blog devoted to the little grey cat was lau~ "cat,NULL,c(\"cat\", \"cat\")"            
                      2     2 dog cat fight          Dogs have soft fur and tails so do cats Do cats like to chase their tails  there are many fights going on and this is just an example text                    "c(\"dog\", \"cat\"),c(\"cat\", \"cat\"),~
                      3     3 bird cat issues        A cat and bird can coexist in a home but you will have to take certain me~ Some cats will not care about a pet bird at all while others will make it its lif~ "c(\"bird\", \"cat\"),c(\"cat\", \"bird\"~                                                                                    
                      

                      Using the navigator.share() api, how do I share only the information for one object?

                      copy iconCopydownload iconDownload
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      shareButtons.forEach((shareButton, i) => { // `i` is the index of the associated data for the shareButton
                        shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title, // use index to get associated article data
                              url: blogArticles[i].url
                            };
                            // ... remaining code ...
                      
                      const blogArticles = [
                        {
                          date: "11/24/2021",
                          title: "the querySelectorAll DOM API",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1600/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/queryselectorall-dom-api.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "the difference between named and anonymous functions",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1601/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/difference-between-named-and-anonymous-functions.html"
                        },
                        {
                          date: "11/24/2021",
                          title: "css animations explained",
                          minutesToRead: 10,
                          tags: ["javascript", "html"],
                          image: "https://placekitten.com/1602/900",
                          altText: "image of kittens",
                          teaser:
                            "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
                          url: "articles/css-animations-explained.html"
                        }
                      ];
                      
                      //pass blogArticles data
                      function blogArticlesTemplate(articles) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      document.getElementById('blogTeaserList').innerHTML = `
                        ${blogArticles.map(blogArticlesTemplate).join('')}
                        `;
                      
                      
                      const shareButtons = document.querySelectorAll(".share");
                      
                      if ("share" in navigator) {
                        shareButtons.forEach((shareButton, i) => {
                          shareButton.addEventListener("click", () => {
                            const shareData = {
                              title: "example.com",
                              text: blogArticles[i].title,
                              url: blogArticles[i].url
                            };
                            navigator
                              .share(shareData)
                              .then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          });
                        });
                      } else {
                        shareButtons.forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>
                      const blogArticles = [{ date: "11/24/2021", title: "the querySelectorAll DOM API", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1600/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/queryselectorall-dom-api.html" }, { date: "11/24/2021", title: "the difference between named and anonymous functions", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1601/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/difference-between-named-and-anonymous-functions.html" }, { date: "11/24/2021", title: "css animations explained", minutesToRead: 10, tags: ["javascript", "html"], image: "https://placekitten.com/1602/900", altText: "image of kittens", teaser: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod", url: "articles/css-animations-explained.html" } ];
                      
                      function blogArticlesTemplate(articles, i) {
                        return `
                          <div class="tease-post">
                            <div class="tease-post__container">
                              <h5 class="tease-post__meta">
                                <span class="tease-post__meta--date">${articles.date}</span>
                              </h5>
                              <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
                              <div class="tease-post__details">
                                <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
                                <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
                                <h4 class="share" data-article="${i}"><i class="fa fa-share-alt"></i> Share</h4>
                              </div>
                              <hr>
                              <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
                              <div class="tease-post__text">
                                <p>${articles.teaser}</p>
                      
                                <a href="//${articles.url}" class="tease-post__more">[read more]</a>
                              </div>      
                            </div>
                          </div>    
                        `;
                      }
                      
                      // `insertAdjacentHTML` is generally faster than using `.innerHTML`, as it doesn't need to tear down the old child-nodes of the container.
                      const blogTeasterListElem = document.getElementById('blogTeaserList');
                      blogTeasterListElem.insertAdjacentHTML("beforeend", blogArticles.map(blogArticlesTemplate).join('')); 
                      
                      if ("share" in navigator) {
                        blogTeasterListElem.addEventListener("click", (e) => {
                          const clickedItem = e.target;
                          if (clickedItem.matches(".share")) {
                            const idx = Number(clickedItem.dataset.article);
                            navigator
                              .share({
                                title: "example.com",
                                text: blogArticles[idx].title,
                                url: blogArticles[idx].url
                              }).then(() => {
                                console.log("Shared", shareData);
                              })
                              .catch(console.error);
                          }
                        });
                      } else {
                        document.querySelectorAll(".share").forEach((shareButton) => {
                          shareButton.style.display = "none";
                        });
                      }
                      img {
                        width: 100%;
                        height: auto;
                      }
                      
                      .tease-post {
                        max-width: 350px;
                        background: lightgray;
                      }
                      
                      .share {
                        cursor: pointer;
                      }
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                      <div id="blogTeaserList"></div>

                      .Net HttpClient.GetStreamAsync() behaves differently to .GetAsync()

                      copy iconCopydownload iconDownload
                      async Task Main()
                      {   
                          HttpClient httpclient = new HttpClient();
                          var imageUrl = "https://tenlives.com.au/wp-content/uploads/2020/09/Found-Kitten-0-8-Weeks-Busy-scaled.jpg";
                          var downloadTasks = Enumerable.Range(0, 15)
                              .Select(async u =>
                              {
                                  try
                                  {
                                      //Option 1) - this will fail
                                      var response = await httpclient.GetAsync(imageUrl, HttpCompletionOption.ResponseHeadersRead);
                                      //End Option 1)
                      
                                      //Option 2) - this will succeed
                                      //var response = await httpclient.GetAsync(imageUrl, HttpCompletionOption.ResponseContentRead);
                                      //End Option 2)
                      
                                      response.EnsureSuccessStatusCode();
                                      var stream = await response.Content.ReadAsStreamAsync();
                                      return stream;
                                  }
                                  catch (Exception e)
                                  {
                                      Console.WriteLine($"Error downloading image");
                                      throw;
                                  }
                              }).ToList();
                      
                          try
                          {
                              await Task.WhenAll(downloadTasks);
                          }
                          catch (Exception e)
                          {       
                              Console.WriteLine("================ Failed to download one or more image " + e.Message);
                          }
                          Console.WriteLine($"Successful downloads: {downloadTasks.Where(t => t.Status == TaskStatus.RanToCompletion).Count()}");
                      }
                      
                      //I removed the uninterested code for the question
                      public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
                      {
                          TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
                          client.SendAsync(request, cancellationToken).ContinueWith(task =>
                          {
                              HttpResponseMessage response = task.Result;
                              if(completionOption == HttpCompletionOption.ResponseHeadersRead)
                              {
                                  tcs.TrySetResult(response);
                              }
                              else
                              {
                                  response.Content.LoadIntoBufferAsync(int.MaxValue).ContinueWith(contentTask =>
                                  {
                                      tcs.TrySetResult(response);
                                  });
                              }
                          });
                          return tcs.Task;
                      }
                      
                      var downloadTasks = Enumerable.Range(0, 15)
                      .Select(async u =>
                      {
                          try
                          {
                              var stream = await httpclient.GetStreamAsync(imageUrl);
                              stream.Dispose(); //Free buffer
                              return stream;
                          }
                          catch (Exception e)
                          {
                              Console.WriteLine($"Error downloading image");
                              throw;
                          }
                      }).ToList();
                      
                      async Task Main()
                      {   
                          HttpClient httpclient = new HttpClient();
                          var imageUrl = "https://tenlives.com.au/wp-content/uploads/2020/09/Found-Kitten-0-8-Weeks-Busy-scaled.jpg";
                          var downloadTasks = Enumerable.Range(0, 15)
                              .Select(async u =>
                              {
                                  try
                                  {
                                      //Option 1) - this will fail
                                      var response = await httpclient.GetAsync(imageUrl, HttpCompletionOption.ResponseHeadersRead);
                                      //End Option 1)
                      
                                      //Option 2) - this will succeed
                                      //var response = await httpclient.GetAsync(imageUrl, HttpCompletionOption.ResponseContentRead);
                                      //End Option 2)
                      
                                      response.EnsureSuccessStatusCode();
                                      var stream = await response.Content.ReadAsStreamAsync();
                                      return stream;
                                  }
                                  catch (Exception e)
                                  {
                                      Console.WriteLine($"Error downloading image");
                                      throw;
                                  }
                              }).ToList();
                      
                          try
                          {
                              await Task.WhenAll(downloadTasks);
                          }
                          catch (Exception e)
                          {       
                              Console.WriteLine("================ Failed to download one or more image " + e.Message);
                          }
                          Console.WriteLine($"Successful downloads: {downloadTasks.Where(t => t.Status == TaskStatus.RanToCompletion).Count()}");
                      }
                      
                      //I removed the uninterested code for the question
                      public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
                      {
                          TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
                          client.SendAsync(request, cancellationToken).ContinueWith(task =>
                          {
                              HttpResponseMessage response = task.Result;
                              if(completionOption == HttpCompletionOption.ResponseHeadersRead)
                              {
                                  tcs.TrySetResult(response);
                              }
                              else
                              {
                                  response.Content.LoadIntoBufferAsync(int.MaxValue).ContinueWith(contentTask =>
                                  {
                                      tcs.TrySetResult(response);
                                  });
                              }
                          });
                          return tcs.Task;
                      }
                      
                      var downloadTasks = Enumerable.Range(0, 15)
                      .Select(async u =>
                      {
                          try
                          {
                              var stream = await httpclient.GetStreamAsync(imageUrl);
                              stream.Dispose(); //Free buffer
                              return stream;
                          }
                          catch (Exception e)
                          {
                              Console.WriteLine($"Error downloading image");
                              throw;
                          }
                      }).ToList();
                      
                      async Task Main()
                      {   
                          HttpClient httpclient = new HttpClient();
                          var imageUrl = "https://tenlives.com.au/wp-content/uploads/2020/09/Found-Kitten-0-8-Weeks-Busy-scaled.jpg";
                          var downloadTasks = Enumerable.Range(0, 15)
                              .Select(async u =>
                              {
                                  try
                                  {
                                      //Option 1) - this will fail
                                      var response = await httpclient.GetAsync(imageUrl, HttpCompletionOption.ResponseHeadersRead);
                                      //End Option 1)
                      
                                      //Option 2) - this will succeed
                                      //var response = await httpclient.GetAsync(imageUrl, HttpCompletionOption.ResponseContentRead);
                                      //End Option 2)
                      
                                      response.EnsureSuccessStatusCode();
                                      var stream = await response.Content.ReadAsStreamAsync();
                                      return stream;
                                  }
                                  catch (Exception e)
                                  {
                                      Console.WriteLine($"Error downloading image");
                                      throw;
                                  }
                              }).ToList();
                      
                          try
                          {
                              await Task.WhenAll(downloadTasks);
                          }
                          catch (Exception e)
                          {       
                              Console.WriteLine("================ Failed to download one or more image " + e.Message);
                          }
                          Console.WriteLine($"Successful downloads: {downloadTasks.Where(t => t.Status == TaskStatus.RanToCompletion).Count()}");
                      }
                      
                      //I removed the uninterested code for the question
                      public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
                      {
                          TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
                          client.SendAsync(request, cancellationToken).ContinueWith(task =>
                          {
                              HttpResponseMessage response = task.Result;
                              if(completionOption == HttpCompletionOption.ResponseHeadersRead)
                              {
                                  tcs.TrySetResult(response);
                              }
                              else
                              {
                                  response.Content.LoadIntoBufferAsync(int.MaxValue).ContinueWith(contentTask =>
                                  {
                                      tcs.TrySetResult(response);
                                  });
                              }
                          });
                          return tcs.Task;
                      }
                      
                      var downloadTasks = Enumerable.Range(0, 15)
                      .Select(async u =>
                      {
                          try
                          {
                              var stream = await httpclient.GetStreamAsync(imageUrl);
                              stream.Dispose(); //Free buffer
                              return stream;
                          }
                          catch (Exception e)
                          {
                              Console.WriteLine($"Error downloading image");
                              throw;
                          }
                      }).ToList();
                      

                      Community Discussions

                      Trending Discussions on kitten
                      • HTML adding text beside an Image
                      • Static Files in express
                      • How can I use UI kitten OverflowMenu component properly?
                      • How to remove this blue outline in iOS browsers for UI Kitten input component
                      • java.lang.NoSuchMethodError: No virtual method setSkipClientToken(Z)V in class Lcom/facebook/GraphRequest;
                      • Pandas sum over rows using conditional substring of other columns
                      • queries on users' comments in MongoDB
                      • How to search through a directory and find corresponding video and xml files and rename?
                      • R - If column contains a string from vector, append flag into another column
                      • Using the navigator.share() api, how do I share only the information for one object?
                      Trending Discussions on kitten

                      QUESTION

                      HTML adding text beside an Image

                      Asked 2022-Apr-10 at 21:42

                      Recently started learning html and I have an difficulty to adding text to right an image.
                      Thats the code so far:

                      .image {
                        display: inline-block;
                      }
                      .image1 {
                        width: 400px;
                        height: 200px;
                        overflow: hidden;
                        border: 1px solid black;
                      }
                      .image1 img {
                        margin: 0px 0px -105px -155px;
                      }
                      .image2 {
                        width: 400px;
                        height: 200px;
                        overflow: hidden;
                        border: 1px solid black;
                      }
                      .image2 img {
                        margin: 0px 0px -105px -55px;
                      }
                      .image3 {
                        width: 400px;
                        height: 200px;
                        overflow: hidden;
                        border: 1px solid black;
                      }
                      .image3 img {
                        margin: 0px 0px -110px -25px;
                      }
                      font {
                        text-shadow: 1px 1px black;
                      }
                      <div id="banner" style="overflow: hidden; display: inline-block;">
                        <div class="image1" style="max-width: 50%; max-height: 50%;">
                          <img src="https://images.unsplash.com/photo-1618813576930-12cf7ad6dc31?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8a2l0dGllc3xlbnwwfHwwfHw%3D&w=1000&q=80" width="400px">
                          <font face="arial" size="5px" color="orange"> <b>Ginger cat</b></font>
                      </div>
                      <hr>
                      <div class="image2" style="max-width: 50%; max-height: 50%;">
                        <img src="https://image.shutterstock.com/image-photo/british-shorthair-kitten-silver-color-260nw-1510641710.jpg" width="373px">
                        <font face="arial" size="5px" color="White" ><b>White cat</b></font>
                      </div>
                      <hr>
                      <div class="image3" style="max-width: 50%; max-height: 50%;">
                        <img src="https://images.unsplash.com/photo-1595433707802-6b2626ef1c91?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max" width="275px">
                        <font face="arial" size="5px" color="Black"> <b>Serious cat</b></font>
                      </div>
                      </div>

                      Tried using style="float:left"; or style="float:right" but it didnt work at all. Also do you have any book or video recommandation for HTML?

                      Thanks for any help.

                      ANSWER

                      Answered 2022-Apr-09 at 08:04

                      Best way is to use position You can read about position here

                      and for your code you can use this as your css

                      .image1 {
                          position: relative;
                      }
                      
                      .image1 font {
                          position: absolute;
                          bottom: 10px;
                          left: 10px;
                      }
                      

                      also for html tutorial I suggest DevEd on youtube Hope it was useful

                      Source https://stackoverflow.com/questions/71806218

                      Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                      Vulnerabilities

                      No vulnerabilities reported

                      Install kitten

                      To build Kitten, run:. from this directory. That will build the common, master, and client subprojects.

                      Support

                      For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

                      DOWNLOAD this Library from

                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      Share this Page

                      share link
                      Consider Popular Continuous Deployment Libraries
                      Try Top Libraries by cloudera
                      Compare Continuous Deployment Libraries with Highest Support
                      Compare Continuous Deployment Libraries with Highest Quality
                      Compare Continuous Deployment Libraries with Highest Security
                      Compare Continuous Deployment Libraries with Permissive License
                      Compare Continuous Deployment Libraries with Highest Reuse
                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      • © 2022 Open Weaver Inc.