Create the original download link after checking the domain

I have put such a code in the functions.php file for the download links of my site:

// Define the function to generate the shortcode
 function generate_download_shortcode( $atts ) {

  // Get the file path from the shortcode attributes
  $file_path = $atts['file'];

  // Get the upload directory information
  $upload_dir = wp_upload_dir();

  // Get the base URL of the upload directory
  $base_url = $upload_dir['baseurl'];

  // Get the filename without extension
  $filename = basename($file_path, '.' . pathinfo($file_path)['extension']);

  // URL encode the filename
  $encoded_filename = urlencode($filename);

  // Combine base URL, index.php, and encoded filename
  $download_link = $base_url . '/index.php/' . $encoded_filename . '.' . pathinfo($file_path)['extension'] . '?token=' . md5( time() . rand() ) . '&rate=500kbps';

  return '<a href="' . $download_link . '" class="download-link">Download</a>';
}

// Add the shortcode to WordPress
add_shortcode( 'dow', 'generate_download_shortcode' );

// Add the JavaScript to handle the download link click
add_action( 'wp_footer', 'download_link_script' );

function download_link_script() {
  ?>
  <script>
  // Add event listener to the window load event
  window.addEventListener('load', function() {

  // Get all elements with the "download-link" class
  var downloadLinks = document.getElementsByClassName('download-link');

  // Add click event listener to each download link
  for (var i = 0; i < downloadLinks.length; i++) {
  downloadLinks[i].addEventListener('click', downloadLinkClickHandler);
  }

  // Function to handle download link click
  function downloadLinkClickHandler(event) {

  // Prevent default link action
  event.preventDefault();

  // Get the download link element
  var linkElement = event.target;

  // Start countdown
  var countdown = 3;
  var interval = setInterval(function() {
  linkElement.textContent = 'Download (' + countdown + ')';
  countdown--;
  if (countdown === 0) {
  clearInterval(interval);

  // Update the link element with the original download link without parameters
  linkElement.href = linkElement.href.split('?')[0];
  linkElement.textContent = 'Download';
  }
  }, 1000);

  }

  });
  </script>
  <?php
}

// Add rewrite rule to handle download requests
add_rewrite_rule('^download/([^/]+)/?', 'index.php?page_id=123&file=$matches[1]', 'top');

  
  // Function to handle download requests
  function handle_download_request() {
  
  if ( !isset($_GET['download_file']) ) {
  return; // No download request
  }
  
  $file_path = urldecode($_GET['download_file']);
  
  // Check if user has permission to access the file
  if ( !user_can( 'edit_files' ) && !file_exists($file_path) ) {
  wp_die('You do not have permission to download this file.');
  }
  
  // Generate the download link with parameters
  $download_link = generate_download_link( $file_path );
  
  // Start the download process
  startDownload($file_path);
  
  }
  
  // Add the action to handle download requests
  add_action( 'init', 'handle_download_request' );

This code will correctly apply the new link and apply the download speed to the download link I want.

Using scripting, I have created a condition that if the user clicks on the link from the main address of the site, after three seconds the token and speed limit will be removed from the link and the main link will be displayed for the user.

But my code has two big problems:
1- When the seconds count ends and a new link is created, the file must be downloaded immediately, which does not happen.

2- When the link is clicked again, the seconds counter starts counting again, which is completely wrong. If the user clicks a second time or a few more times, the file should be downloaded instead of the seconds counting down.

Please help me to solve this problem.

Is it possible to fetch data from a server component using a client component in NextJs

I appologise for the way the question is phrased.
I have this server component called auth.ts that retrieves some user details after they’ve logged in.
This is my server side component //auth.ts

export const validateRequest = cache(
  async (): Promise<
    { user: LuciaUser; session: Session } | { user: null; session: null } > => {
    await dbConnect();
    const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
    if (!sessionId) {
      return {
        user: null,
        session: null,
      };
    }

    const result = await lucia.validateSession(sessionId);

    if (!result) {
      return {
        user: null,
        session: null,
      };
    }

    const profileAttributes = await getProfileAttributes(result.user);

    if (!profileAttributes) {
      return {
        user: null,
        session: null,
      };
    }
    result.user.profile = {
      ...profileAttributes,
      //We return "id" instead of "_id" to be consistent with
      //the way lucia returns the user object.
      //aternatively, don't return profile id at all
      //depending on the requirements of the app
      _id: undefined,
      id: profileAttributes._id,
    };

    try {
      if (result.session && result.session.fresh) {
        const sessionCookie = lucia.createSessionCookie(result.session.id);
        cookies().set(
          sessionCookie.name,
          sessionCookie.value,
          sessionCookie.attributes
        );
      }
      if (!result.session) {
        const sessionCookie = lucia.createBlankSessionCookie();
        cookies().set(
          sessionCookie.name,
          sessionCookie.value,
          sessionCookie.attributes
        );
      }
    } catch (error) {
      console.log('error message', error);
    }
    return JSON.parse(JSON.stringify(result));
  }
);


Trying to retrieve the data in a server component seems straightforward, I did something like this

export default async function Home() {
  const { user } = await validateRequest();
return(

<>
{user? (
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white">
   Welcome, {user?.profile?.firstName}!
</h2> ):(
<>
<Link href="/auth/login">
 Go to Login
 <LogIn />
 </Link>
</>

)
}

</>

Tried to apply the same logic in a client component and all hell broke loose, I’ve been struggling to find a solution for a long time.

Please can someone explain what to do so that I can learn and take note of it for future references. Thanks in advance

Display name in react-native (Ios, Android)

My application name is (Feruz Academy) but on the phone it is displayed like this (FeruzAcad…) why is this?

I searched but didn’t find a solution, looked in different libraries, tried nothing, nothing changed. Maybe I didn’t find the answer, please help)

how to use swc to make ast restore be code segment

My code segment is this:

<>
    <Divider orientation="left">{resultLinkTitle}</Divider>
    <Intension />
    <Form form={form} name="auditForm" ref={auditFormRef}>
      <Form.Item label="files">
        <Button type="link" onClick={() => handleDownLoadFile(aduitInfo?.fileUrl)}>
          download
        </Button>
      </Form.Item>
    </Form>
  </>

then I use swc.parse get ast.But I cannot get the original code with swc.printSync.It will get error unknown variant JSXElement, expected ModuleorScript“.
How can I do?

I what to get the original code with swc.

Why does fluent-ffmpeg not work in an async Promise?

I am trying to fluent-ffmpeg synchronously and await its finishing. I wrapped it in a promise and wait for it to resolve.

The problem is that it stops doing anything after the second chunk has been processed. I get an output of:

Processing: NaN% done
Processing: 12.710198594559962% done
Processing: 25.846254358525282% done

And then it just hangs and does nothing. I am using NodeJS’s PassThrough to pipe the data from ffpmeg to. If I remove the promise and just it normally, then it works fine. But I need the promise because there is other code after this that must wait for ffmpeg to finish first.

import {PassThrough} from 'node:stream';
import FFMpeg from 'fluent-ffmpeg';

let PassThroughStream = new PassThrough();
    
function ffmpegPromise() {
               return new Promise((resolve, reject) => {
                    FFMpeg('/testvid.mp4')
                        .videoCodec('libx264')
                        .audioCodec('libmp3lame')
                        .size('640x480')
                        // Stream output requires manually specifying output formats
                        .format('mp4')
                        .outputOptions('-movflags dash')
                        .on('progress', function (progress) {
                            console.log('Processing: ' + progress.percent + '% done');
                        })
                        .on('error', function (err) {
                            console.log('An error occurred: ' + err.message);
                            reject(err);
                        })
                        .on('end', function () {
                            console.log('FFMpeg Processing finished!');
                            resolve()
                        })
                        .output(PassThroughStream, {end: false}).run();
    
            })
    
            }

await ffmpegPromise();

Getting POST 500 Internal server error while sending request via ajax call

I have a logic where I want to insert data into database. SO I am sending ajax request through my local machine. Below is the code for the same..

$("#btnSubmitCT").on('click', function () {       

        var valid = validateForm();
        if (valid) {
            $("#divLoadingPanel").show();
            SubmitForm_CE().done(function () {
                $("#divLoadingPanel").hide();
            });
        }

    });
    
    
function SubmitForm_CE() {
    try {

        var req_id = "";
        var umsGroupNameBy = CurrentGroupName;
        var umsGroupIdBy = CurrentGroupID;
        var loginUserName = LoginUserName;
        var spanType = $(spantypeid + ' option:selected').val().toUpperCase();
        var r4gState = $(r4gstatediv + ' option:selected').text();
        var UG_LEN = parseFloat($('#UGLEGCE_txt').html()).toFixed(4);
        var AR_LEN = parseFloat($('#ARLEGCE_txt').html()).toFixed(4);

        var fixedUG = parseFloat($('#UGLEGCE_txt').html()).toFixed(4);
        var fixedAR = parseFloat($('#ARLEGCE_txt').html()).toFixed(4);

        var linkId;
        var spanId;
        var createdId;
        if (spanType == AppConfig.SpanTypeInter.toUpperCase()) {
            linkId = "";
            spanId = $(spnLinkId).text();
            createdId = "SPAN ID: " + spanId;
        }
        else {
            spanId = "";
            linkId = $(spnLinkId).text();
            createdId = "LINK ID: " + linkId;
        }

        var mZoneCode = $(mzoneid + ' option:selected').val();
        var mZoneText = $(mzoneid + ' option:selected').text();
        var mZoneArr = mZoneText.split('/');
        var mZoneName = mZoneArr[0];
        var operationType = $(activitytypeid + ' option:selected').val().toUpperCase();

        var pendSpanLeg = parseFloat($(pendingSpanLen).html());
        var neLeg = parseFloat($(spnspanlength).html());        
        var offerHoto = parseFloat($(hotoofferbyct).val());
        var offerDate = $('#ctOfferdatepicker').val();
        
        var remark = $(remarkct).val();
        var offerValue = JSON.stringify({ "OFFERHOTO": offerHoto, "OFFERLIT": "0", "NE_LEG": neLeg, "HOTOCOMPLETED": "0", "LITCOMPLETED": "0" });
        var statusId = getHotoStatusID(offerValue);
        var umsGroupObj = JSON.parse(UMSGroupDetails)
        var GroupToValue = "";
        var umsGroupNameTo = "";
        var umsGroupIdTo;
        $.each(umsGroupObj, function (index, element) {
            if (element.GroupName == UserGrouop.FE) {
                umsGroupNameTo = element.GroupName;
                umsGroupIdTo = element.GroupID;
            }
        });
        var Values = { "SPANID": spanId, "LINKID": linkId, "CREATEDBY": loginUserName, "MZONECODE": mZoneCode, "MZONENAME": mZoneName, "NELEG": neLeg, "UGLEG": UG_LEN, "ARLEG": AR_LEN, "STATUSID": statusId, "HOTOOFFERDATE": offerDate, "REMARK": remark, "HOTOOFFERLEG": offerHoto, "UMSGROUPIDBY": umsGroupIdBy, "UMSGROUPNAMEBY": umsGroupNameBy, "UMSGROUPIDTO": umsGroupIdTo, "UMSGROUPNAMETO": umsGroupNameTo, "SPANTYPE": spanType, "R4GState": r4gState };

        return $.ajax({
            type: "POST",
            url: AppConfig.PrefixURL + "App/InitiateWF_CT",
            data: JSON.stringify(Values),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            //            async: false,
            beforeSend: function () {
            },
            success: function (response) {
                alert(response);
                var datalist = JSON.parse(response);
                var state = datalist.split('|')[0];
                var msg = "";
                if (state == "SUCCESS") {
                    msg = "Request Id: " + datalist.split('|')[1] + " has been created for " + createdId;
                    req_id = datalist.split('|')[1];                    
                    hideInfoWindow();                    
                    hideLoading();
                    jAlert(msg, ValidationMessageConfig.Title, function () {
                        $(spandetailsdiv).hide();
                        deleteSpanListDatatable_CT($(spnLinkId).text());
                    });

                } else if (state == "WARNING" || state == "EXISTS") {
                    msg = datalist.split('|')[1];
                    hideInfoWindow();
                    hideLoading();
                    jAlert(msg, ValidationMessageConfig.Title, function () {
                        $(spandetailsdiv).hide();
                        deleteSpanListDatatable_CT($(spnLinkId).text());
                    });
                } else {
                    hideLoading();
                    msg = datalist.split('|')[1]
                    jAlert(msg, ValidationMessageConfig.Title, function () {
                        $(spandetailsdiv).hide();
                        deleteSpanListDatatable_CT($(spnLinkId).text());
                    });
                    AppLog.getLogger('error', "Error occured during processing new job");
                }
            },
            error: function (response) {
               // jAlert(ErrorMessageForMethods.initiateWF, ErrorMessageForMethods.Title);
                //AppLog.getLogger('error', "Error occured during processing new job");
                // hideLoading();
                alert('NO Record created 1');
                hideLoading();
            }
        });
    } catch (e) {
        $(spandetailsdiv).hide();
        hideLoading();
        alert('NO Record created 2');
        //jAlert(ErrorMessageForMethods.initiateWF, ErrorMessageForMethods.Title);
        //AppLog.getLogger('error', "Error occured during processing new job");

    }
}    

url: AppConfig.PrefixURL + "App/InitiateWF_CT", here it is telling that http://localhost:2126/App/InitiateWF_CT 500 (Internal Server Error)

Can you suggest what is wrong in this ?

i want all images selected one by one with a click on image from html, how do i loop over them in javascript?

I am building a memory game and want to loop through all images one by one in javascript.
The idea is to put it in the ImageUrl variable i have made connected to the newCard variable and loop over every image one by one by click on html image.

I’ve tried to research it but can’t find any answers.

This is what i have for code:

function populateField() {
    for (let i = 0; i < myCardSet.length; i++) {
        let newTile = document.createElement('div');
        let newCard = document.createElement('img');
        let imageURL = document.getElementById('field').getElementsByTagName('img')
    for (let i of imageURL) {
        let ImageSrc = i.getAttribute('name')
        console.log(ImageSrc.substring(ImageSrc.lastIndexOf('/') + 1))
    }
        newCard.setAttribute('src', imageURL)
        newCard.setAttribute('name', imageURL)
        newTile.appendChild(newCard)
        myField.appendChild(newTile)
        let img = {
            src: 'cover.png',
            class: '.covered'
        }
    }
}
<body>

    <div id="field"><img src="../begin/img/calf.jpg" alt="" name="calf">
        <img src="../begin/img/cat.jpg" alt="" name="cat">
        <img src="../begin/img/chick.jpg" alt="" name="chick">
        <img src="../begin/img/cow.jpg" alt="" name="cow">
        <img src="../begin/img/dog.jpg" alt="" name="dog">
        <img src="../begin/img/duck.jpg" alt="" name="duck">
        <img src="../begin/img/goat.jpg" alt="" name="goat">
        <img src="../begin/img/goose.jpg" alt="" name="goose">
        <img src="../begin/img/hen.jpg" alt="" name="hen">
        <img src="../begin/img/horse.jpg" alt="" name="horse">
        <img src="../begin/img/kitten.jpg" alt="" name="kitten">
        <img src="../begin/img/lamb.jpg" alt="" name="lamb">
        <img src="../begin/img/pig.jpg" alt="" name="pig">
        <img src="../begin/img/piglet.jpg" alt="" name="piglet">
        <img src="../begin/img/puppy.jpg" alt="" name="puppy">
        <img src="../begin/img/rooster.jpg" alt="" name="rooster">
        <img src="../begin/img/sheep.jpg" alt="" name="sheep">
        <img src="../begin/img/veal.jpg" alt="" name="veal">
        <img src="../begin/img/cat.jpg" alt="" name="cat">
        <img src="../begin/img/chick.jpg" alt="" name="chick">
        <img src="../begin/img/cow.jpg" alt="" name="cow">
        <img src="../begin/img/dog.jpg" alt="" name="dog">
        <img src="../begin/img/duck.jpg" alt="" name="duck">
        <img src="../begin/img/goat.jpg" alt="" name="goat">
        <img src="../begin/img/goose.jpg" alt="" name="goose">
        <img src="../begin/img/hen.jpg" alt="" name="hen">
        <img src="../begin/img/horse.jpg" alt="" name="horse">
        <img src="../begin/img/kitten.jpg" alt="" name="kitten">
        <img src="../begin/img/lamb.jpg" alt="" name="lamb">
        <img src="../begin/img/pig.jpg" alt="" name="pig">
        <img src="../begin/img/piglet.jpg" alt="" name="piglet">
        <img src="../begin/img/puppy.jpg" alt="" name="puppy">
        <img src="../begin/img/rooster.jpg" alt="" name="rooster">
        <img src="../begin/img/sheep.jpg" alt="" name="sheep">
        <img src="../begin/img/veal.jpg" alt="" name="veal">
    </div>

    <script src="js/memory.js" type="module"></script>
</body>

Please help,
Thanks already!

My frontend is unable to connect to the backend address

“My frontend can’t connect to the backend address, but I can make a POST request with curl. Here is the browser error: net::ERR_CONNECTION_REFUSED at (index):9 when trying to POST to http://127.0.0.1:5000/process-data.”
Front-end code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
<script>
function sendData() {
    // Make sure the URL is the Flask application address, usually http://127.0.0.1:5000/process-data if it's local
    fetch('http://127.0.0.1:5000/process-data', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({message: 'Hello, backend!'}),
    })
    .then(response => response.json())
    .then(data => {
        // Display the data returned from the backend on the webpage
        document.getElementById('response').innerText = data.reply;
    })
    .catch((error) => {
        console.error('Error:', error);
    });
}
</script>
</head>
<body>

<button onclick="sendData()">Send data to backend</button>
<div id="response">The response from the backend will be displayed here.</div>

</body>
</html>

Back-end code:

from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/process-data', methods=['POST'])
def process_data():
    # Retrieve the data sent from the front-end
    data = request.json
    print(data)  # Just as an example, the data might need to be processed in a real application

    # Suppose this is the response after processing
    reply = {'reply': f"Backend received your message: {data.get('message')}"}

    # Return the processed result to the front-end
    return jsonify(reply)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

This translation includes the comments within the code for clarity.

I’ve been trying to enable interaction between the front end and the back end to create a website.

Rehype to render hashtag as url

Trying to make a something like #tag render as a URL the markdown editor MDEditor using rehypeRewrite. Here’s what I have so far

const REG = /B(#[a-zA-Z]+b)(?!;)/gi;

<MDEditor 
    style={{width: "100%", height: "100%"}} 
    minHeight={500} 
    value={value} 
    onChange={(event) => {
        setValue(event || '');
    }} 
    previewOptions={{
        rehypePlugins: [
            [
            rehypeRewrite,
            {
                rewrite: (node : any, index: any, parent: any) => {
                if (node.type === "element" && node.tagName === "p") {
                    let text = getCodeString(node.children);
                    if (REG.test(text)) {
                        node.children = [
                        {
                            type: 'link',
                            url: 'https://example.com',
                            children: [{type: 'text', value: text} ]
                        }];
                    }
                }}
            },
        ]],
    }}
/>

The regex properly matches the text but instead of the node being replaced with a link, it just doesn’t render anything.

Any guidance on what I may be doing wrong would be much appreciated

Svelte how to have duplicate keys in a keyed each

I have a simple clicker app, that stores the number as a list (500 being [5,0,0]). Here’s my current implementation:

{#each numbers as number (number)}
    <h1 class="score-text">{number}</h1>
{/each}

It can count up to 10, but 11 won’t work as they are the same number.

each.js:135  Uncaught (in promise) Error: Cannot have duplicate keys in a keyed each: Keys at index 0 and 1 with value '1' are duplicates
    at validate_each_keys (each.js:135:10)
    at Object.update [as p] (ScoreCounter.svelte:13:23)
    at update (scheduler.js:119:30)
    at flush (scheduler.js:79:5)

What could I do to fix this?

Just placing a bunch of elements with numbers[0] through numbers[15] works, but I feel like there must be a better way.

Best Way to Convert js object

I try to Upload Files with Ajax Post and form.serialize, but my req.body looks like this:

    {
    _uploadFilesMessage: '',
    mailgroupIDS: '',
    'field[0][fileID]': '0',
    'field[0][filename]': 'img_nature_wide27.jpg',
    'field[0][filetype]': '2',
    'field[0][selTag]': '322444370236',
    'field[1][fileID]': '1',
    'field[1][filename]': 'img_snow_wide10.jpg',
    'field[1][filetype]': '2',
    'field[1][selTag]': '322444370236'
  }

but i need it like this:

{
  _uploadFilesMessage: '',
  mailgroupIDS: '',
  field: [
    {
      fileID: '0',
      filename: 'img_nature_wide27.jpg',
      filetype: '2',
      selTag: '322444370236'
    },
    {
      fileID: '1',
      filename: 'img_snow_wide10.jpg',
      filetype: '2',
      selTag: '322444370236'
    }
  ]
}

What is the most efficient way to convert the req.body ?

Returning value from apps script (doPost) to client, after calling an external API

I am trying to invoke an apps script deployed web app (doPost method) and get a response back to the client app (this could be HTTP client like Postman/Bruno or simple javascript app).
The deployed web app would call an external API and return its result.
When I try this I am getting a message (HTML) saying “The script completed but the returned value is not a supported return type.”
If I do not call external API and try to return a default / hard coded object from doPost, the client is getting the response properly (as a JSON).
Console log statements are showing proper output values
Please suggest if there is a way out.

Deployed web app (apps script) is

let respout= { "jokeid": 0, "errcode": 0, "errmsg": "na" };
function doPost() 
{
    console.log('inside doPost func', respout);
    try 
      {  //If tried to return above respout with out executing "jokefun()", below statement works with client
         //return ContentService.createTextOutput(JSON.stringify(respout)).setMimeType(ContentService.MimeType.JSON);
         return jokefunc().then( res => {
                                          respout={ "jokeid": res.id,"errcode": 200,"errmsg": "success" };
                                          console.log('resp out val in then func',respout);
                                          return ContentService.createTextOutput(JSON.stringify(respout)).setMimeType(ContentService.MimeType.JSON);
                                        })
        
      } 
    catch (error) 
      {
        console.log('Exception in doPost', error);
      }
    
}

async function jokefunc() 
{
  try
    {
      const API_URL = "https://official-joke-api.appspot.com/random_joke";
      const response = UrlFetchApp.fetch(API_URL);
      const responseText = response.getContentText();
      const jsonData = JSON.parse(responseText);
      console.log('Fetch called', jsonData);
      return jsonData; // Return the fetched data object
    }
  catch(error)
    {
      console.error('Some thing went wrong',error)
    }
}

Reading the user’s console errors from a chrome extension

I am creating a small extension for personal use that should help me analyze errors using an API I made. In order to do that it requires read access to the console of the active tab. Is there a way to achieve that? I tried overriding the console methods but then found out the extension’s js is isolated from the tab’s, so kinda lost here.

Any help would be much appreciated, thanks in advance.

Making a fade in when in sight thing but it messed up my :hover effect for a card thing

I have 8 divs in a div called card-group these cards should expand and there are also little cards which go to the edge this worked then a added more text at the bottom and the on screen fade in but it messed up the :hover effect.
Here is one of the :hover statements there are 8 of these:
style.css

.card-group:hover  .big-card:nth-child(1) {
  transform: translate(-75%,16%) rotate(-24deg);
  cursor: pointer;
}

then theres also the seen part in style.css

.hidden {
  opacity: 0;
  transition: all 1s;
  filter: blur(5px);
  transform: translateX(-100%);
}
.visible {
  opacity: 1;
  filter: blur(0px);
  transform: translateX(0);
}

Here is the code from app.js with a defer propertie

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) =>{
    if (entry.isIntersecting) {
      entry.target.classList.add('visible'); // Use a different class for visibility
    } else {
      entry.target.classList.remove('visible');
    }
  });
});

const hiddenElements = document.querySelectorAll('.hidden');
hiddenElements.forEach((element) => observer.observe(element));

const cards = document.querySelectorAll('.card');

cards.forEach(card => {
  card.addEventListener('mouseenter', () => {
    card.classList.add('hovered');
  });

  card.addEventListener('mouseleave', () => {
    card.classList.remove('hovered');
  });
});

I was expecting this card group to open like the 8 :hover things said it should but instead it just did nothing the effect where the hidden and visible things fade in works but the hover does not. Thanks in advance if there was a way I could have written this better please let me know.