Navigating the Ethical Implications of AI in Content Creation: Lessons from the Organic Food Industry

Disclaimer: This article was developed based on a human-generated concept using Artificial Intelligence technologies. In compliance with our commitment to responsible AI use and transparency, and in anticipation of sadly non-existent UN regulations, we inform our readers about AI’s involvement in creating this content. Please note that the consumption of AI-generated content and its potential long-term effects on mental health remain understudied. We advise you to exercise caution and prioritize your well-being when engaging with AI-generated content.

Introduction:

As AI systems like ChatGPT become more advanced and integrated into our daily lives, it’s crucial to consider the ethical implications of their widespread use, particularly on human content creators and their motivations. One way to approach this issue is by drawing parallels with the organic food industry and the GDPR. In this article, we’ll explore the analogy between organic vs heavily processed food and discuss strategies to promote responsible AI use in content creation.

Organic vs Heavily Processed Content:

Organic content, like organic food, is created by humans and reflects human experiences, emotions, and creativity. Heavily processed content, on the other hand, is AI-generated or modified, deriving from large datasets and potentially lacking the authenticity of human-created content. Just as we prioritize the freshness and health benefits of organic food, it’s essential to recognize the value of organic content in fostering genuine human connections and creativity.

Lessons from the Food Industry and GDPR:

  1. Clear labeling: Indicate when content is AI-generated or modified, allowing consumers to make informed decisions about the content they consume.
  2. Certification process: Establish a certification process for AI-generated content to ensure it meets specific quality and ethical standards.
  3. Responsible consumption: Promote awareness of the benefits and potential drawbacks of AI-generated content to foster a culture of responsible consumption and informed decision-making.
  4. Support for “organic” content: Celebrate human creators and recognize the value they bring to society, ensuring their contributions are not overshadowed by AI-generated content.
  5. Regulation and oversight: Implement policies and regulatory frameworks to ensure responsible AI development and use while supporting transparency, accountability, and public trust.

Strategies for a Balanced AI-Content Ecosystem:

  1. Develop mechanisms to recognize and credit original content creators when AI is used to adapt or build upon their work.
  2. Invest in research focusing on AI’s potential to augment human creativity and problem-solving, rather than replacing it entirely.
  3. Enforce AI model development in a way that preserves and credits the source of data/content below each generated content.
  4. Implement ways to verify if a particular creator’s content was used to train a model or not, and provide options for content creators to opt-out, so their content will be removed from training data and “erased” from the model.
  5. Establish ethical guidelines for AI development and use, ensuring it serves humanity’s best interests and respects people’s rights.

Conclusion:

Navigating the ethical implications of AI in content creation requires thoughtful consideration, open discussion, and collaboration between AI developers, policymakers, and society. By learning from the organic food industry and the GDPR, and implementing similar strategies, we can create an environment that encourages responsible AI use while preserving the importance of human creativity and connection.

PlanZed – welcome to my new project

Hi all, it’s a pity I have no time to share my discovering here more often, and I have so much of them!
I finished developing first phase of PlanZed project – cloud mind map app and it’s now available for free!
Welcome to try the app, I need feedback so much.
Here is in brief what do we have under the hood:

  • React – Next.js
  • Material UI as basement + I had to implement a lot of specific widgets
  • Hosted on Vercel
  • Mongo as a DB
  • No I don’t use jsPlumb – svg arrows are hand-written.
  • Pan/Zoom also hand-written (will have a separate post about this, don’t use css translate for pan, let browser scroll it for you, it’s much better!)
  • Built-in custom icons search from materialdesignicons.com
  • I extented already existing in materialdesignicons keywords by synonyms using wordnet (thanks for ‘node-wordnet’)
  • The project is currently trying to support three languages, same icons search do – icons keywords, extend by synonyms, are translated using Google API
  • No images upload – it will cost for me to store / manage them, so later as a paid option
  • But there is built-in search of free photos from pexels.com – in most cases that’s enough for mind map(they already support localized search)

Here is a GitHub repo serving as a community for PlanZed

Several screenshots from the project:

How to make “Fire-and-forget” HTTP request from Node.js without waiting for response.

Lambda functions at zeit/now v2 platform have default execution timeout 10s.
Another limitation important to consider:
– the process gets killed right after the response was sent.
When you have a job to be done in the lambda, not required immediately to prepare HTTP response (e.g. writing log to the database)
– it’s a good idea to send a response to the client ASAP and do rest of the work “in the background”.
But there are no built-in ways to do such things in zeit/now v2 lambdas.

The only way everybody talks but nobody tried is to extract such task into separate lambda and call it via another HTTP request.
It sounds easy, but let’s take a closer look:

  • λ1 was asked for a response. If it says anything – the game is over, no job can be done anymore.
  • so let λ1 ask λ2 to do rest of the job
  • and then respond to the original request

Ok?
How to ask λ2 to do something?

  1. make a request → get 200OK → respond
    get 200OK? λ2 is lambda too. It can’t say anything until the job is finished or it will be killed.
    So λ1 still have to wait for all the job is done before responding.

  2. make a request → “let it go” → respond
    How to let it go? Don’t pass any callback, don’t wait for any promise.
    But this way response to the original request will be sent too soon and λ1 will be killed.
    λ2 will have no chance to receive a request, parse args and perform any action.

  3. Make sure λ2 got the request, but don’t wait for a response:

//delegate.js
const https = require('https');
module.exports = async (host, message) => {
  message = JSON.stringify(message);
  var options = {
    hostname: host,
    method: 'POST',
    path: '/lambda2',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': Buffer.byteLength(message),
    },
  };
  await new Promise((resolve, reject) => {
    let req = https.request(options);
    req.on('error', (e) => {
      console.error(`problem with request: ${e.message}`);
      reject(e);
    });
    req.write(message);
    req.end(() => {
      console.log("NOW it's not λ1's problem anymore.");
      resolve();
    });
  });
};
//lambda1.js
const delegate = require('./delegate');
module.exports = async (req, res) => {
  let host = req.headers['x-now-deployment-url'];
  await delegate(host,'Hey, you, λ2! Did you hear an order?');
  res.end('Yes, my Master! Will be done!')
};
//lambda2.js
module.exports = async (req, res) => {
  console.log("Oh, so much to be done! Let's start immediately!");
  await new Promise((resolve) => {
    setTimeout(() => {
      console.log('Nothing was done successfully!');
      send(res, 200);
      resolve();
    }, 2000);
  });
};

Hope this piece of code will save someone’s work day!

Show hidden part of truncated text on hover/touch

Here are three ways to show hidden part of truncated text on touch/hover without Javascript

1) overflow:visible

Hover over or touch me to see the full version of this string. It looks like replaced by tooltip
some other stuff

Pros:

  • No Javascript
  • Good readability
  • Small and simple cross-browser CSS code
  • Easy to render.

Contras:

  • Need extra markup (inner span wrapper)
  • Requires all the parents of the text container to be wide enough or have ‘overflow’ porperty to be ‘visible’.

Here is SCSS with comments:

.overflow-tip {
  /* make it single-line */
  white-space:nowrap;
  /* truncate by container's size */
  overflow-x: hidden;
  /* add three dots */
  text-overflow: ellipsis;
  /* on touch or hover */
  &:active, &:hover {
    /* show hidden part outside of parent */
    overflow-x: visible;
    /* and with inner span */
    span {
      /* allow to overlap siblings */
      position: relative;
      /* make readable design */
      background-color: PaleGoldenRod;
      border: 1px solid gray;
      padding: 3px;
      /* compensate padding and border size to avoid jerking */
      margin-left: -4px;
    }    
  }
}

2) direction:rtl

Hover over or touch me to see the end of this long string.
some other stuff

Pros:

  • No Javascript
  • No extra HTML
  • Super simple CSS

Contras:

  • Not so readable for very long string or very short container
    Commented scss:
.rtl-switch {
  /* make it single-line */
  white-space:nowrap;
  /* truncate by container's size */
  overflow-x: hidden;
  /* add three dots */
  text-overflow: ellipsis;
  /* on touch or hover */
  &:active, &:hover {
    /* make text have right to left direction */
    direction: rtl;
    /* fix three dots overlapping issue*/
    padding-left:10px;
    &:after {
      /* fix brackets in rtl mode */
      content: "\200E‎";
    }
  }
}

3) marquee (transition left)

Hover over or touch me to see animated scrolling of this string. Fancy but buggy. May be still can be improved.
some other stuff

Pros:

1) Fancy
2) Displays whole string in a limited space

Contras:

1) Bloated HTML (needs two extra spans)
2) Bad readability for long strings
3) Animation bug on mouse out or not truncated string(may be still can be fixed, I’ll see later)
4) Animation can load CPU on heavy page
5) Needs hardcoded offset, or will be scrolled until container is not empty
Let’s see some code:

.marquee {
  /* Single line */
  white-space:nowrap;
  /* Truncate by container size */
  overflow: hidden;
  /* Both spans */
  span {
    /* Allow to set size */
    display: inline-block;
    /* Size same as container when not hovered to allow ellipsis */
    width: 100%;
    /* Second span */
    span {
      /* Turn animation on */
      @include transition(left 4s linear);
      /* Allow position manipulation */
      position: relative;
      /* truncate by container's size */
      overflow-x: hidden;
      /* add three dots */
      text-overflow: ellipsis;
      /* Explicitly declare initial position to animate well */
      left: 0px;
    }   
  }
  /* on touch or hover */
  &:active, &:hover {
    /* Both spans */
    span {
      /* resize to contain whole string without truncation. */
      width: auto;
      /* Second span */
      span {
        /* Animated scroll by length of first span (100% of parent),
  which equals to length of string, not a container.
  Also shift final point back by width of container (500px)
  to not finish with empty box
  and pitch by 15px - I don't know why, may be to compensate paddings */
        left:calc(500px - 15px - 100%);//
      }
    }    
  }

Here is a codepen to play:

See the Pen Expand cropped string on hover/touch, pure CSS by Yuri Gor (@yurigor) on CodePen.0

Pan and Zoom in jsPlumb Community Edition with Dagre and jQueryUI Draggable

See the Pen Pan and Zoom in jsPlumb Community Edition with Dagre and jQueryUI Draggable by Yuri Gor (@yurigor) on CodePen.0

Chart with draggable HTML elements as nodes, connected by jsPlumb library.
“Pan&Zoom” feature missing in Comunity Edition implemented by using “jQuery Panzoom” plugin.
Nodes dragging implemented by jQueryUI Draggable, to compensate scale distortion.
Dagre layout library used for demonstration.

I use static predefined html in this example:

<!-- .container - just part of your page,
where you want to render diagram -->
<div class="container">
  <!-- .panzoom - wrapper div, panzoom plugin will transform it.
        Use it for worksheet element styling -->
  <div class="panzoom">
    <!-- .diagram - wrapper div to be used by jsPlumb.
         It will have zero height, so no visual CSS works here. -->
    <div class="diagram">
      <!-- .item - diagram nodes, must have unique id's
           to be able connect them by jsPlumb. -->
      <div id="i0"  class="item">Root</div>
      <div id="i1" class="item">Child 1</div>
      <div  id="i11" class="item">Child 1.1</div>
      <div  id="i12" class="item">Child 1.2</div>
      <div id="i2" class="item">Child 2</div>
      <div id="i21" class="item">Child 2.1</div>
      <div id="i3" class="item">Child 3</div>
    </div>
  </div>
</div>

Links between nodes declared in js array:

var links = [
  { from: "i0", to: "i1" },
  { from: "i1", to: "i11" },
  { from: "i1", to: "i12" },
  { from: "i0", to: "i2" },
  { from: "i2", to: "i21" },
  { from: "i0", to: "i3" },
];

Initializing of panzoom:

$panzoom = $container.find('.panzoom').panzoom({
      minScale: minScale,//0.4
      maxScale: maxScale,//2
      increment: incScale,//0.1
      cursor: "",/*empty string prevents panzoom
          from changing cursor styles defined in your css.*/
    }).on("panzoomstart",function(e,pz,ev){
      $panzoom.css("cursor","move");//set "move" cursor on start only
    })
    .on("panzoomend",function(e,pz){
      $panzoom.css("cursor","");//restore cursor
    });

Mouse wheel support and pan while drag begins outside diagram:

$panzoom.parent()
    .on('mousewheel.focal', function( e ) {
      //if Control pressed then zoom
      if(e.ctrlKey||e.originalEvent.ctrlKey)
      {
        e.preventDefault();
        var delta = e.delta || e.originalEvent.wheelDelta;
        var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
        $panzoom.panzoom('zoom', zoomOut, {
           animate: true,
           exponential: false,
        });
      }else{//else pan (touchpad and Shift key works)
        e.preventDefault();
        var deltaY = e.deltaY || e.originalEvent.wheelDeltaY || (-e.originalEvent.deltaY);
        var deltaX = e.deltaX || e.originalEvent.wheelDeltaX || (-e.originalEvent.deltaX);
        $panzoom.panzoom("pan",deltaX/2,deltaY/2,{
          animate: true,
          relative: true,
        });
      }
    })
    //on start store initial offsets and mouse coord
    .on("mousedown touchstart",function(ev){
      var matrix = $container.find(".panzoom").panzoom("getMatrix");
      var offsetX = matrix[4];
      var offsetY = matrix[5];
      var dragstart = {x:ev.pageX,y:ev.pageY,dx:offsetX,dy:offsetY};
      $(ev.target).css("cursor","move");
      $(this).data('dragstart', dragstart);
    })
    //calculate mouse offset from starting pos and apply it to panzoom matrix
    .on("mousemove touchmove", function(ev){
      var dragstart = $(this).data('dragstart');
      if(dragstart)
      {
        var deltaX = dragstart.x-ev.pageX;
        var deltaY = dragstart.y-ev.pageY;
        var matrix = $container.find(".panzoom").panzoom("getMatrix");
        matrix[4] = parseInt(dragstart.dx)-deltaX;
        matrix[5] = parseInt(dragstart.dy)-deltaY;
        $container.find(".panzoom").panzoom("setMatrix",matrix);
      }
    })
    .on("mouseup touchend touchcancel", function(ev){
      $(this).data('dragstart',null);
      $(ev.target).css("cursor","");
    });
  });

Make nodes draggable by jQueryUI/draggable:

var currentScale = 1;
  $container.find(".diagram .item").draggable({
    start: function(e){
      var pz = $container.find(".panzoom");
      //save current scale factor to consider it later
      currentScale = pz.panzoom("getMatrix")[0];
      $(this).css("cursor","move");
      //disable panzoom, to avoid panning while dragging node
      pz.panzoom("disable");
    },
    drag:function(e,ui){
      /*compensate current scale while dragging,
           else pointer and node will have different speeds*/
      ui.position.left = ui.position.left/currentScale;
      ui.position.top = ui.position.top/currentScale;
      //it's possible to have not connected nodes, so let's check it.
      if($(this).hasClass("jsplumb-connected"))
      {
        plumb.repaint($(this).attr('id'),ui.position);
      }
    },
    stop: function(e,ui){
      var nodeId = $(this).attr('id');
      if($(this).hasClass("jsplumb-connected"))
      {
        plumb.repaint(nodeId,ui.position);
      }
      $(this).css("cursor","");
      $container.find(".panzoom").panzoom("enable");
    }
  });