Snippets Collections
/*========================================================
  Rise 360 compulsory CSS
  For use in all Digital Learning and Development Rise 360 courses.
  Version 1.0
  Last updated 04/11/2024
==========================================================*/

/*Global variables – edit these variables to suit your course design.
==========================================================*/

:root {
  --custom-theme-colour-button-hover-opacity: .9; /*This sets the opacity of buttons and checkboxes that use the theme colour, such as continue buttons.Lower value equals ligher hover colour.*/
  --custom-carousel-prev-next-hover-colour: #000; /*This sets the hover state colour of the previous and next buttons on the quote carousel and image carousel blocks.*/
}

/*Global CSS edits
==========================================================*/

/*Links > Hover state: Add a background colour and border.*/
.brand--linkColor a:hover {
  outline: solid 3px rgba(0, 0, 0, .1); /*Using transparancy prevents surrounding text, such as full stops, from vanishing.*/
  background-color: rgba(0, 0, 0, .1) !important;
}

/*Cover page
==========================================================*/

/*Cover page > Start module button: Remove all caps, increase font size, decrease font weight, adjust padding.*/
.cover__header-content-action-link-text{
  text-transform: none;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: .1rem;
}
.cover__header-content-action-link {
  padding: 0.8rem 2.9rem !important;
}

/*Cover page > body text: Increase font size and change colour.*/ 
.cover__details-content-description.brand--linkColor {
  color: #000;
  font-size: 1.7rem;
}

/*Cover page > Section titles: Increase font size, remove all caps, darken border line.*/
.overview-list__section-title {
  border-bottom: .1rem solid #717376; /*Colour of the lesson icons.*/
  font-size: 1.4rem;
  text-transform: none;
}

/*Cover page > lesson list: Increase font size.*/
.overview-list-item__title {
  font-size: 1.4rem;
}

/*Navigation menu
==========================================================*/

/*Navigation menu > % progress indicator: Remove all caps, increase font size.*/
.nav-sidebar-header__progress-text {
  text-transform: none !important;
  font-size: 1.4rem !important;
}

/*Navigation menu > Section titles: Remove all caps, increase font size.*/
.nav-sidebar__outline-section-toggle-text {
  text-transform: none;
  font-size: 1.4rem;
}
.nav-sidebar__outline-section-toggle:after {
  border-bottom: 1px solid #717376 !important;
}

/*Navigation menu > Lesson titles: Increase font size.*/
.nav-sidebar__outline-section-item__link {
  font-size: 1.4rem !important;
}

/*Lesson header
==========================================================*/

/*Lesson header > Lesson counter: Increase font size, remove italics.*/
.lesson-header__counter {
  font-size: 1.4rem;
  font-style: normal;
  margin-bottom: 1.3rem !important;
}

/*Text blocks
==========================================================*/

/*Paragraph
----------------------------------------------------------*/

/*Paragraph with heading
----------------------------------------------------------*/

/*Paragraph with subheading
----------------------------------------------------------*/

/*Heading
----------------------------------------------------------*/

/*Subheading
----------------------------------------------------------*/

/*Columns
----------------------------------------------------------*/

/*Table
----------------------------------------------------------*/


/*Statement blocks
==========================================================*/

/*Statement A
----------------------------------------------------------*/

/*Statement B
----------------------------------------------------------*/

/*Statement C
----------------------------------------------------------*/

/*Statement D
----------------------------------------------------------*/

/*Note
----------------------------------------------------------*/


/*Quote blocks
==========================================================*/

/*Quote A
----------------------------------------------------------*/

/*Quote B
----------------------------------------------------------*/

/*Quote C
----------------------------------------------------------*/

/*Quote D
----------------------------------------------------------*/

/*Quote on image
----------------------------------------------------------*/

/*Quote carousel
----------------------------------------------------------*/

/*Quote carousel > Progression circles and arrows: Change arrow hover colour, change progression cirle hover opacity and scale.*/
.block-quote--carousel .carousel-controls-next,
.block-quote--carousel .carousel-controls-prev {
  transition: color 0.3s;
}
.block-quote--carousel .carousel-controls-next:hover,
.block-quote--carousel .carousel-controls-prev:hover {
  color: var(--custom-carousel-prev-next-hover-colour); 
}
.carousel-controls-item-btn {
  transition: all 0.15s ease-in-out;
}
.carousel-controls-item-btn:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
  color: var(--custom-theme-hover-bg, #202d60);
}


/*List blocks
==========================================================*/

/*Numbered list
----------------------------------------------------------*/

/*Checkbox list
----------------------------------------------------------*/

/*Checkbox list > Checkboxes: Move the checkboxes to the front and change the hover colour.*/
.block-list__checkbox {
  z-index: 2;
  transition: all .15s ease-in-out;
}
.block-list__checkbox:hover {
  background-color: var(--color-theme-decorative);
  opacity: var(--custom-theme-colour-button-hover-opacity);
}

/*Bulleted list
----------------------------------------------------------*/


/*Image blocks
==========================================================*/

/*Image blocks > Caption: Increase font size. This can be changed by manually adjusting the font size in Rise.*/
.block-image__caption, .block-gallery__caption {
  font-size: 1.4rem !important;
}

/*Image centered
----------------------------------------------------------*/

/*Image full width
----------------------------------------------------------*/

/*Image & text
----------------------------------------------------------*/

/*Text on image
----------------------------------------------------------*/


/*Gallery blocks
==========================================================*/

/*Carousel
----------------------------------------------------------*/

/*Carousel > Progression circles and arrows: Change arrow hover colour, change progression cirle hover opacity and scale.*/
.block-gallery-carousel__container .carousel-controls-next,
.block-gallery-carousel__container .carousel-controls-prev {
  transition: color 0.3s;
}
.block-gallery-carousel__container .carousel-controls-next:hover,
.block-gallery-carousel__container .carousel-controls-prev:hover {
  color: var(--custom-carousel-prev-next-hover-colour);
}
/*Note that the hover state of the progression circles is modified in the Quote carousel section.*/

/*Two column grid
----------------------------------------------------------*/

/*Three column grid
----------------------------------------------------------*/

/*Four column grid
----------------------------------------------------------*/


/*Multimedia blocks
==========================================================*/

/*Audio
----------------------------------------------------------*/

/*Audio > Play/puase button and scrub slider: Increase size and gap between. Change hover scale.*/
.audio-player__play {
  margin-right: 1.6rem;
}
.audio-player__play .svg-inline--fa {
  height: 1.7rem;
  transition: all 0.15s ease-in-out;
}
.audio-player__play .svg-inline--fa:hover {
  transform: scale(1.2);
}
.audio-player__tracker-handle{
  height: 100%;
}
.audio-player__tracker-handle-icon>svg {
  height: 1.5rem;
  width: 1.5rem;
}
.audio-player__tracker-handle-icon{
  transition: all 0.15s ease-in-out;
}
.audio-player__tracker-handle-icon:hover {
  transform: scale(1.2);
}
.audio-player__tracker-handle-icon:active {
  transform: scale(1.2);
}

/*Audio > track line: Make line thicker.*/
.audio-player__tracker-bar {
  border-top: .16rem solid var(--color-track);
}
.audio-player__tracker:after {
  border-top: .16rem solid var(--color-runner);
}

/*Audio > Timer: Increase font size.*/
.audio-player__timer {
  font-size: 1.2rem;
}

/*Audio > Caption: Increase font size. This can be changed by manually adjusting the font size in Rise.*/
.block-audio__caption {
  font-size: 1.4rem;
}

/*Video
----------------------------------------------------------*/

/*Video > Caption: Change font size to 14px.*/
.block-video__caption {
  font-size: 1.4rem;
}

/*Embed
----------------------------------------------------------*/

/*Attachement
----------------------------------------------------------*/

/*Attachement: Add hover colour.*/
.block-attachment:hover {
  background: #ebebeb;
}

/*Code snippet
----------------------------------------------------------*/

/*Code snippet > Caption: Increase font size.*/
.block-text__code-caption p {
  font-size: 1.4rem;
}

/*Interactive blocks
==========================================================*/

/*Accordion
----------------------------------------------------------*/

/*Tabs
----------------------------------------------------------*/

/*Tabs > Titles: Remove all caps, increase font size and reduce letter spacing.*/
.blocks-tabs__header-item{
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: .04rem;
}

/*Labeled graphic
----------------------------------------------------------*/

/*Labeled graphic > pop-up text: Set font size. This can be changed by manually adjusting the font size in Rise.*/
.bubble__content {
  font-size: 1.6rem;
}

/*Process
----------------------------------------------------------*/

/*Process > Navigation arrows: Change hover state opacity.*/
.process-arrow {
  transition: opacity .3s !important;
}
.process-arrow:hover {
  opacity: .8;
}

/*Process > Start button: Change focus state outline.*/
.process-card__start:focus, .process-card-mobile__start:focus {
  outline-offset: 0.4rem;
}

/*Process > Start button: Change hover state opacity.*/
.process-card__start:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
}

/*Process > Start button: Remove all caps, increase font size and letter spacing.*/
.process-card__start-text, .process-card-mobile__start-text  {
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: .1rem;
}

.block-process-card__start-btn {
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: .1rem;}


.process-card__start-icon {
  height: 1.3rem !important;
  width: 1.3rem !important;
}

/*Process > Start again: Remove all caps, increase font size and letter spacing.*/
.process-card__restart, .process-card-mobile__restart {
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: .1rem;
  font-weight: 700;
}
  
/*Process > Start again: Add hover state.*/
.process-card__restart {
  transition: background-color 0.3s;
  border-radius: 5px;
}
.process-card__restart:hover {
  background-color: #ebebeb;
}

/*Scenario
----------------------------------------------------------*/

/*Scenario block > Continue buttons, Start over buttons: Remove all caps, increase font size and letter spacing.*/
.scenario-block__text__continue {
  line-height: 2rem;
}
.scenario-block__text__continue, .scenario-block__dialogue__button, .scenario-block__text__end span {
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: .1rem;
}

/*Scenario block > Response: Increase font size.*/
.scenario-block__response .fr-view {
    font-size: 1.6rem;
}

/*Scenario block > Response: Change hover colour.*/
.scenario-block__response__inner:hover {
  background-color: #ebebeb;
}
  
/*Scenario > Continue buttons: Change hover opacity.*/
.scenario-block__text__continue:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
}
  
/*Scenario > Continue buttons: Change focus state outline.*/
.scenario-block__text__continue:focus {
  outline-offset: 0.4rem;
}
  
/*Scenario > Response buttons: Change hover state.*/
.scenario-block__dialogue__button {
  transition: all .3s;
}
.scenario-block__dialogue__button:hover {
  background-color: #ebebeb;
  transform: translateX(1rem);
}
  
/*Scenario > Start over: Change hover state.*/
.scenario-block__text__end {
  transition: all .3s;
  color: var(--color-theme-decorative);
  padding: 1rem;
  margin-top: 1rem;
}
.scenario-block__text__end:hover {
  background-color: #ebebeb;
  border-radius: 5px;
}


/*Sorting activity
----------------------------------------------------------*/

/*Sorting activity > Restart button: Remove all caps, change font size, colour and letter spacing.*/
.block-sorting-activity .restart-button__content {
  color: var(--color-theme-decorative);
  border-radius: 5px;
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: .1rem;
  font-weight: 700;
}

/*Sorting activity > Restart button: Add a hover state.*/
.block-sorting-activity .deck__title {
  margin-bottom: 1rem;  
  padding-bottom: .6rem;
  border-bottom: .1rem solid rgba(0, 0, 0, .2);
}
.block-sorting-activity .restart-button {
  margin-top: 0rem;
  border: none;
  padding: 1rem;
  border-radius: 5px;
  min-height: 7.45rem;
}
.block-sorting-activity .restart-button {
  transition: background-color 0.3s;
}
.block-sorting-activity .restart-button:hover {
  background-color: #ebebeb;
}


/*Timeline
----------------------------------------------------------*/

/*Flashcard grid
----------------------------------------------------------*/

/*Flashbard stack
----------------------------------------------------------*/

/*Flashcard stack > Previous and Next button: Change hover state.*/
.block-flashcards-slider__arrow--next, .block-flashcards-slider__arrow--prev {
  transition: opacity .3s;
}
.block-flashcards-slider__arrow--next:hover, .block-flashcards-slider__arrow--prev:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
}

/*Flashcard stack > Slide counter: Remove italics.*/
.block-flashcards-slider__progress-text {
  font-style: normal;
}

/*Flashcard stack > Progress line: Increase thickness.*/
.block-flashcards-slider__progress-line {
  border-bottom: max(.2rem, 2px) solid var(--color-progress-track);
  position: relative;
}
.block-flashcards-slider__progress-runner {
  border-bottom: max(.2rem, 2px) solid var(--color-theme-decorative);
}

/*Button
----------------------------------------------------------*/

/*Button and Button stack > Button: Remove all caps, increase font size and line height.*/
.blocks-button__button {
  transition: all .3s;
  text-transform: none;
  font-size: 1.5rem;
  line-height: 3.9rem;
}

/*Button and Button stack > Button: Change hover state.*/
.blocks-button__button:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
}

/*Button and Button stack > Button: Offset the focus state outline.*/
.blocks-button__button:focus {
  outline-offset: .4rem;
}

/*Button stack
----------------------------------------------------------*/

/*Storyline
----------------------------------------------------------*/


/*Knowledge check blocks AND Quiz lesson
==========================================================*/

/*Knowledge check/Quiz > Options: remove extra space between question options and submit button/feedback box.*/
.block-knowledge .quiz-card__interactive {
  margin-bottom: 3rem;
}

/*Knowledge check/Quiz > Submit/Next buttons: Remove all caps and increase font size.*/
.quiz-card__button{
  transition: opacity .3s;
  text-transform: none;
  font-size: 1.5rem;
}
  
/*Knowledge check/Quiz > Submit/Next buttons: Change hover state.*/
.quiz-card__button:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
}
  
/*Knowledge check/Quiz > Submit/Next buttons: Offset the focus state outline.*/
.quiz-card__button:focus {
  outline-offset: 0.4rem;
}

/*Knowledge check/Quiz > 'Correct/Incorrect' label: Increase font size.*/
.quiz-card__feedback-label {
  font-size: 1.4rem;
}

/*Knowledge check/Quiz > Feedback body text: Increase font size, align left and ensure color is black. */
.quiz-card__feedback-text {
  font-size: 1.6rem;
  text-align: left;
  color: #000;
}

/*Knowledge check > Try again button: Remove all caps, increase font size and change to theme colour. Note that the Rise 360 label text must also be lowercase.*/
.block-knowledge__retake-text {
  text-transform: none;
  font-size: 1.4rem;
}
.block-knowledge__retake {
  color: var(--color-theme-decorative)
}

/*Knowledge check > Try again button: Change hover state.*/
.block-knowledge__retake-content {
  transition: background-color 0.3s;
  border-radius: 5px;
  padding: 1rem;
  margin: -1rem /*Negative margin pushes the margin out into the padding area to create a larger hover state without having to change the padding for the normal state.*/
}
.block-knowledge__retake-content:hover {
  background-color: #ebebeb;
}

/*Multiple choice
----------------------------------------------------------*/

/*Multiple response
----------------------------------------------------------*/

/*Fill in the blank
----------------------------------------------------------*/

/*Fill in the blank > 'Acceptable responses' label: Increase font size and remove italics.*/
.quiz-fill__options {
  font-size: 1.4rem;
  font-style:normal;
}

/*Matching
----------------------------------------------------------*/

/*Matching: Increase font size to 16px.*/
.quiz-match__item-content {
  font-size: 1.5rem;
}

/*Quiz
----------------------------------------------------------*/

/*Quiz > 'Lesson X of Y' label: Increase font size, letter spacing and remove italics.*/
.quiz-header__counter {
  font-size: 1.4rem;
  font-style: normal;
  letter-spacing: .05rem;
}

/*Quiz > 'Start assessment' label: Remove all caps, increase font size, move icon to the left.*/
.quiz-header__start-quiz {
  transition: all .3s;
  text-transform: none;
  font-size: 1.5rem;
  border-radius: 5px;
  padding: 1rem;
  margin: -1rem;
}
.quiz-header__start-quiz [class*=icon-] {
  margin-left: .6rem;
}

/*Quiz > 'Start assessment' label: Add hover state.*/
.quiz-header__start-quiz:hover {
  background-color: #ebebeb;
}

/*Quiz > 'Question' label: Remove italics and increase font size.*/
.quiz-card__step-label {
  font-size: 1.4rem;
  font-style: normal;
  letter-spacing: .05rem;
  font-weight: 400;
}
@media (max-width: 47.9375em) {
  .quiz-card__counter {
    font-size: 2.2rem;
  }
}

/*Quiz > Quiz results odemeter: Increase font size on all elements.*/
.odometer__score-label, .odometer__passlabel, .odometer__passpercent  {
  font-size: 1.4rem;
  text-transform: none;
}

/*Quiz > Quiz results 'Try again' button: Remove all caps, change font colour, size, weight and letter spacing, adjust padding.*/
.quiz-results__footer .restart-button__content {
  transition: background-color 0.3s;
  color: var(--color-theme);
  text-transform: none;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: .1rem;
  padding: 1rem;
  margin: -1rem;
  border-radius: 5px;
}

/*Quiz > Quiz results 'Try again' button: Add hover state.*/
.quiz-results__footer .restart-button__content:hover {
  background-color: #ebebeb;
}


/*Draw from question bank
----------------------------------------------------------*/


/*Chart blocks
==========================================================*/

/*Bar chart
----------------------------------------------------------*/

/*Line chart
----------------------------------------------------------*/

/*Pie chart
----------------------------------------------------------*/


/*Divider blocks
==========================================================*/

/*Continue
----------------------------------------------------------*/
  
/*Continue: Change hover state.*/
.continue-btn {
  transition: opacity 0.3s;
}
.continue-btn:hover {
  opacity: var(--custom-theme-colour-button-hover-opacity);
}

/*Continue: Offset the focus state outline.*/
.continue-btn:focus {
  outline-offset: 0.4rem;
}

/*Divider
----------------------------------------------------------*/

/*Numbered divider
----------------------------------------------------------*/

/*Spacer
----------------------------------------------------------*/


/*CSS edits by firstname lastname on DD/MM/YYYY.*/

/*========================================================
  Optional CSS edits – Paste all optional CSS edits below this comment.
==========================================================*/


(function () {
    // Create console group for visibility
    function logEvent(event) {
      console.groupCollapsed(
        "%c📡 Tracking Fired:",
        "color: #4caf50; font-weight: bold;",
        event.event || "(no event name)"
      );
      console.log(event);
      console.groupEnd();
    }

    // Monitor every push to dataLayer
    var originalPush = window.dataLayer.push;
    window.dataLayer.push = function () {
      [].slice.call(arguments).forEach(logEvent);
      return originalPush.apply(window.dataLayer, arguments);
    };

    console.log("%cTracking Debugger Active", "color: orange; font-size: 14px;");
  })();
The history of atom started to spread by ancient Greek philosophers then re-invented and developed by John Dalton. Later, the atomic model was discovered by several scientists such as J. J. Thomson, Ernest Rutherford, and Niels Bohr. Then, the Quantum Atomic Model became the topic discussed by many scientists. 
string related_list.Populate_Sales_Tiers(Int Rec_ID)
{
Pages = {1,2,3,4,5,6,7,8,9,10};
Match_Found = false;
responseXML = "<record>";
count = 0;
for each  Page in Pages
{
	Sales_Tier_List = zoho.crm.getRecords("Sales_Tiers",Page,200);
	for each  rec in Sales_Tier_List
	{
		ST_Rec_Id = rec.get("id");
		rec_details = zoho.crm.getRecordById("Sales_Tiers",ST_Rec_Id);
		Sales_Entries = rec_details.get("Sales_Entries");
		if(Sales_Entries != null)
		{
			for each  data in Sales_Entries
			{
				Reservation_id = ifNull(ifNull(data.get("Reservation"),{"id":""}).get("id"),"");
				//info Reservation_id;
				if(Reservation_id == Rec_ID)
				{
					info "Inside if:";
					Tier_Month_and_Year = ifNull(rec.get("Tier_Month_and_Year"),"");
					Name = ifNull(rec.get("Name"),"");
					Tier = ifNull(rec.get("Tier"),"");
					Total_Sales_Value = ifNull(rec.get("Total_Sales_Value"),"");
					Tier_Record_Number = ifNull(rec.get("Tier_Record_Number"),"");
					Sales_Manager_Booked_Unit = ifNull(rec.get("Sales_Manager_Booked_Unit"),"");
					Incentive_Percentage = ifNull(rec.get("Incentive_Percentage"),"");
					info Sales_Manager_Booked_Unit;
					///////////////////////
					///////////////////////////
					responseXML = responseXML + "<row no='" + count + "'>";
					responseXML = responseXML + "<FL val='Sales Tier Name' link='true' url='https://crmsandbox.zoho.com/crm/newsandboxeck/tab/CustomModule55/" + ST_Rec_Id + "'>" + Name + "</FL>";
					responseXML = responseXML + "<FL val='Tier Month and Year' link='true' url=''>" + Tier_Month_and_Year + "</FL>";
					responseXML = responseXML + "<FL val='Incentive Percentage' link='true' url=''>" + Incentive_Percentage + "</FL>";
					responseXML = responseXML + "<FL val='Total Sales Value' link='true' url=''>" + Total_Sales_Value + "</FL>";
					responseXML = responseXML + "<FL val='Sales Manager Booked Unit' link='true' url=''>" + Sales_Manager_Booked_Unit + "</FL>";
					responseXML = responseXML + "<FL val='Tier Record Number' link='true' url=''>" + Tier_Record_Number + "</FL>";
					responseXML = responseXML + "</row>";
					count = count + 1;
				}
			}
		}
	}
}
responseXML = responseXML + "</record>";
return responseXML;
}
<!DOCTYPE html>
<html>
<head>
    <title>Hello World Program</title>
</head>
<body>

<script>
    // Using console.log()
    console.log("Hello World");

    // Using document.write()
    document.write("Hello World");

    // Using alert()
    alert("Hello World");
</script>

</body>
</html>
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>AngularJS Form Validation</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
    <style>
        .error { color: red; }
        input.ng-invalid.ng-touched { border-color: red; }
        input.ng-valid.ng-touched { border-color: green; }
    </style>
</head>
<body ng-controller="FormCtrl">

<h2>Registration Form</h2>

<form name="userForm" ng-submit="submitForm()" novalidate>

    <!-- Name -->
    <label>Name:</label><br>
    <input type="text" name="name"
           ng-model="user.name"
           required
           ng-minlength="3">
    <div class="error" ng-show="userForm.name.$touched && userForm.name.$invalid">
        <span ng-show="userForm.name.$error.required">Name is required.</span>
        <span ng-show="userForm.name.$error.minlength">Minimum 3 characters.</span>
    </div>
    <br><br>

    <!-- Email -->
    <label>Email:</label><br>
    <input type="email" name="email"
           ng-model="user.email"
           required>
    <div class="error" ng-show="userForm.email.$touched && userForm.email.$invalid">
        <span ng-show="userForm.email.$error.required">Email is required.</span>
        <span ng-show="userForm.email.$error.email">Invalid email format.</span>
    </div>
    <br><br>

    <!-- Password -->
    <label>Password:</label><br>
    <input type="password" name="password"
           ng-model="user.password"
           ng-minlength="6"
           required>
    <div class="error" ng-show="userForm.password.$touched && userForm.password.$invalid">
        <span ng-show="userForm.password.$error.required">Password is required.</span>
        <span ng-show="userForm.password.$error.minlength">Minimum 6 cha
add_action( 'wp_head', 'add_recaptcha_site_key' );

function add_recaptcha_site_key() {
    ?>
    <script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY_HERE"></script>
    <?php
}
function wc_varb_price_range( $wcv_price, $product ) {
 
    $prefix = sprintf('%s: ', __('From', 'wcvp_range'));
 
    $wcv_reg_min_price = $product->get_variation_regular_price( 'min', true );
    $wcv_min_sale_price    = $product->get_variation_sale_price( 'min', true );
    $wcv_max_price = $product->get_variation_price( 'max', true );
    $wcv_min_price = $product->get_variation_price( 'min', true );
 
    $wcv_price = ( $wcv_min_sale_price == $wcv_reg_min_price ) ?
        wc_price( $wcv_reg_min_price ) :
        '<del>' . wc_price( $wcv_reg_min_price ) . '</del>' . '<ins>' . wc_price( $wcv_min_sale_price ) . '</ins>';
 
    return ( $wcv_min_price == $wcv_max_price ) ?
        $wcv_price :
        sprintf('%s%s', $prefix, $wcv_price);
}
 
add_filter( 'woocommerce_variable_sale_price_html', 'wc_varb_price_range', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'wc_varb_price_range', 10, 2 );
export const parseCsvText = (text: string, delimiter: string) => {
  const normalized = text.replace(/^\uFEFF/, "");
  const rows: string[][] = [];
  let row: string[] = [];
  let field = "";
  let inQuotes = false;

  for (let i = 0; i < normalized.length; i += 1) {
    const char = normalized[i];

    if (char === '"') {
      if (inQuotes && normalized[i + 1] === '"') {
        field += '"';
        i += 1;
        continue;
      }
      inQuotes = !inQuotes;
      continue;
    }

    if (!inQuotes && char === delimiter) {
      row.push(field);
      field = "";
      continue;
    }

    if (!inQuotes && (char === "\n" || char === "\r")) {
      if (char === "\r" && normalized[i + 1] === "\n") {
        i += 1;
      }
      row.push(field);
      rows.push(row);
      row = [];
      field = "";
      continue;
    }

    field += char;
  }

  if (field.length > 0 || row.length > 0) {
    row.push(field);
    rows.push(row);
  }

  return rows;
};
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
  <meta charset="UTF-8">
  <title>AngularJS Form Validation</title>

  <!-- AngularJS CDN -->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>

  <style>
    body {
      font-family: Arial;
      margin: 40px;
    }
    input.ng-invalid.ng-touched, select.ng-invalid.ng-touched {
      border: 2px solid red;
    }
    input.ng-valid.ng-touched, select.ng-valid.ng-touched {
      border: 2px solid green;
    }
    .error {
      color: red;
      font-size: 14px;
    }
  </style>
</head>

<body ng-controller="FormController">

  <h2>Registration Form</h2>

  <form name="regForm" novalidate>

    <!-- Name -->
    <label>Name:</label><br>
    <input type="text" name="name" ng-model="user.name" required ng-minlength="3">
    <div class="error" ng-show="regForm.name.$touched && regForm.name.$invalid">
      Name is required (min 3 characters)
    </div>
    <br><br>

    <!-- Email -->
    <label>Email:</label><br>
    <input type="email" name="email" ng-model="user.email" required>
    <div class="error" ng-show="regForm.email.$touched && regForm.email.$invalid">
      Enter a valid email address
    </div>
    <br><br>

    <!-- Password -->
    <label>Password:</label><br>
    <input type="password" name="password" ng-model="user.password" required ng-minlength="6">
    <div class="error" ng-show="regForm.password.$touched && regForm.password.$invalid">
      Password must be at least 6 characters
    </div>
    <br><br>

    <!-- Age -->
    <label>Age:</label><br>
    <input type="number" name="age" ng-model="user.age" min="18" max="60" required>
    <div class="error" ng-show="regForm.age.$touched && regForm.age.$invalid">
      Age must be between 18 and 60
    </div>
    <br><br>

    <!-- Gender -->
    <label>Gender:</label><br>
    <input type="radio" ng-model="user.gender" value="Male" required> Male
    <input type="radio" ng-model="user.gender" value="Female"> Female
    <br><br>

    <!-- Country -->
    <label>Country:</label><br>
    <select name="country" ng-model="user.country" required>
      <option value="">--Select--</option>
      <option>India</option>
      <option>USA</option>
      <option>UK</option>
    </select>
    <div class="error" ng-show="regForm.country.$touched && regForm.country.$invalid">
      Please select a country
    </div>
    <br><br>

    <!-- Terms -->
    <label>
      <input type="checkbox" ng-model="user.terms" required> I accept terms and conditions
    </label>
    <br><br>

    <!-- Submit -->
    <button type="submit" ng-disabled="regForm.$invalid">
      Submit
    </button>

  </form>

  <br>

  <!-- Display form data -->
  <h3>Entered Data:</h3>
  <pre>{{ user | json }}</pre>

</body>

<script>
  var app = angular.module("myApp", []);

  app.controller("FormController", function ($scope) {
    $scope.user = {};
  });
</script>

</html>
edit 2: no, i think the referer must be the webpage you extracted the player URL

youtube-dl --referer "URL in browser" "player-url"
def get_folder_in_s3_bucket(bucket, prefix):
    try:
        s3_bucket_data = client.list_objects(Bucket= bucket, Prefix= prefix, Delimiter="/")
        s3_folder_list =  [(prefix_dict['Prefix']).removeprefix(prefix) for prefix_dict in s3_bucket_data.get("CommonPrefixes", None)]
        return s3_folder_list
    except Exception as e:
        print(f"There is an error as {e}")
        return None
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":sunshine: :x-connect: Boost Days: What's on this week :x-connect: :sunshine:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Good morning Melbourne and hope you all had a fab weekend! :sunshine: \n\n Please see below for what's on this week! :yay: BRINGING some summer vibes to the office! "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-28: Wednesday, 28th January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee: :muffin: *Xero Café* – Cookies and Tim Tams \n :coffee: *Barista Special* – Golden Latte \n :flag-fr: Join us at *12.00pm* for some French Lunch in the Wominjeka Breakout Space on Level 3."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-29: Thursday, 29th January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Xero Cafe*: Cookies and Tim tams.\n :coffee: *Barista Special* – Golden Latte \n :Breakfast: :strawberry: Join us at *8.30am -10.30am* for a *Tennis Inspired Breaky* in the Wominjeka Breakout Space on Level 3 . "
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-30: Friday, 30th January ",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":cheers-9743: :aperol-spritz: *Happy Hour:* from 4pm - 5.30pm in the Wominjeka Breakout space. \n\n :yay: *Xero Melbourne Open*: Who is ready to become Melbourne Xero's PING PONG champion? There are prizes to be won, AO merchandise! Sign your team up in the :thread: \n\n :frozen-yoghurt: *Summer Special*: We also have a frozen yoghurt station, YES the best next thing to *YO-CHI*. We are bringing summer vibes to the office and would love to see our Xeros joining us."
			}
		},
		{
			"type": "divider"
		}
	]
}
# Intenta reparar el archivo primero
mv ~/.zsh_history ~/.zsh_history_bad
strings ~/.zsh_history_bad > ~/.zsh_history
fc -R ~/.zsh_history  # Recargar historial
/**
 if rerendering occurs or to stop duplicate events

if (button.dataset.recShareTracked) return;
button.dataset.recShareTracked = "true";

*/



// example

 function recShareTracking() {
        const recUserActions = document.querySelector(".rec-user-actions");

        if (!recUserActions) return;

        const shareButtons = recUserActions.querySelectorAll(
            ".rec-user-actions__cta-button",
        );

        if (!shareButtons.length) return;

        console.log({shareButtons})

        shareButtons.forEach((button) => {
            // Prevent duplicate listeners
            if (button.dataset.recShareTracked) return;
            button.dataset.recShareTracked = "true";

            button.addEventListener("click", (e) => {
                const clickedElement = e.target;
                const isButtonClick =
                    clickedElement === button ||
                    clickedElement.closest(".rec-user-actions__cta-button") ===
                        button;

                if (!isButtonClick) return;

                const buttonTextRaw = button.textContent?.trim() || "";
                const buttonText = buttonTextRaw.replace(/\s+/g, " ").trim() || "";

                if (buttonText) {
                    gtmPush({
                        event: "interaction_click",
                        component_name: "button",
                        click_text: buttonText,
                        click_url: null,
                    });
                }
            });
        });
    }
#include <stdio.h>
#include <omp.h>

int main(int argc, char** argv){
    int partial_Sum, total_Sum;

    #pragma omp parallel private(partial_Sum) shared(total_Sum)
    {
        partial_Sum = 0;
        total_Sum = 0;

        #pragma omp for
        for(int i = 1; i <= 1000; i++){
            partial_Sum += i;
        }

        //Create thread safe region.
        #pragma omp critical
        {
            //add each threads partial sum to the total sum
            total_Sum += partial_Sum;
        }
    }
    printf("Total Sum: %d\n", total_Sum);
    return 0;
}

#include <stdio.h>
#include <omp.h>

int main(int argc, char** argv){
    #pragma omp parallel
    {
        printf("Hello from process: %d\n", omp_get_thread_num());
    }
    return 0;
}
concat('https://crm.zoho.com/crm/org834552803/tab/Potentials/', "Reservations"."Id") as "View Record",
  
    const listItem = target.closest('li.facet-group__list-item');
    if (!listItem) return;

    // Toggle the data-checked attribute
    const wasChecked = listItem.getAttribute('data-checked') === 'true';
    listItem.setAttribute('data-checked', wasChecked ? 'false' : 'true');
Bring your crypto exchange idea to life with confidence. Block Intelligence offers expert Centralized Crypto Exchange Development, combining fast trading engines, strong security, seamless KYC/AML compliance, and intuitive interfaces. Perfect for startups and enterprises, our solutions help you launch smoothly, attract users, and scale in a competitive crypto market. From concept to a fully functional platform, we help you build an exchange that works, grows, and earns trust.

Know more: https://www.blockintelligence.io/centralized-crypto-exchange-development-company
 
WhatsApp: +91 77384 79381

 Email: connect@blockchain.ai.in
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":sunshine: :x-connect: Boost Days: What's on this week :x-connect: :sunshine:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Good morning Brisbane and hope you all had a fab bank holiday weekend! :sunshine: \n\n Please see below for what's on this week! :yay:  "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-28: Wednesday, 29th January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Café Partnership*: Enjoy free coffee and café-style beverages from our Cafe partner *Industry Beans*. \n\n:lunch: *Morning Tea*:from *9am* in the kitchen! \n:lunch: Enjoy a Thai Lunch at 12pm in the kitchen."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-30:Friday, 30th January ",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":cheers-9743: :cheese: *Happy Hour & Happy Friday:* from 3pm - 4pm in the kitchen! Wind down for the week over some drinks and nibbles."
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0?cid=Y19uY2M4cDN1NDRsdTdhczE0MDhvYjZhNnRjb0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Brisbane Social Calendar*>, and get ready to Boost your workdays!\n\nLove,\nWX Team :party-wx:"
			}
		}
	]
}
export const LOCAL_STORAGE_KEYS = {
  CONVERSATION_SELECTED_TAB: "conversation-selected-tab",
  CONVERSATION_RIGHT_PANEL_SHOWN: "conversation-right-panel-shown",
  CONVERSATION_UNPINNED_TABS: "conversation-unpinned-tabs",
};
onSuccess: (_, variables) => {
  clearConversationLocalStorage(variables.conversationId);
},
export const clearConversationLocalStorage = (conversationId: string) => {
  const keys = [
    "conversation-selected-tab",
    "conversation-right-panel-shown",
    "conversation-unpinned-tabs",
  ];

  keys.forEach((prefix) => {
    localStorage.removeItem(`${prefix}-${conversationId}`);
  });
}
Blitzvorschau (Schnellste Methode)

Angenommen, Ihre Daten stehen in Spalte A1 ("Test1234").
Schreiben Sie in Zelle B1 das gewünschte Ergebnis ohne Zahlen ("Test").
Schreiben Sie in Zelle B2 das Ergebnis für die nächste Zeile.
Drücken Sie Strg + E (oder gehen Sie auf Daten -> Blitzvorschau). Excel erkennt das Muster und entfernt alle Zahlen. 
 function footerNavTracking() {
        const footerWrapper = document.querySelector(".footer__wrapper");
        if (!footerWrapper) return;

        footerWrapper.addEventListener("click", (e) => {
            // Find the closest relevant link
            const link = e.target.closest(
                ".footer__col-second-button_wrapper a, .footer__logo-link",
            );
            if (!link) return;

            // Get the URL from the <a> tag
            const url = link.getAttribute("href") || "";

            // Social links
            if (link.matches(".footer__col-second-button_wrapper a")) {
                gtmPush({
                    event: "navigation_click",
                    navigation_type: "footer_nav",
                    click_text: "Social",
                    click_url: url,
                    nav_level: 1,
                });
            }

            // Logo links
            if (link.matches(".footer__logo-link")) {
                gtmPush({
                    event: "navigation_click",
                    navigation_type: "footer_nav",
                    click_text: "logo",
                    click_url: url,
                    nav_level: 1,
                });
            }
        });
    }
 function navigationTracking() {
        const mainNav = document.querySelector(".main-navigation__main");
        if (!mainNav) return;

        const navItems = [
            {
                selector: ".main-navigation__control-link",
                type: "nav-links",
                handler: (e, el) => {
                    const btnTextRaw = el.textContent || "";
                    const btnText = btnTextRaw.replace(/\s+/g, " ").trim();
                    const isPressed =
                        el.getAttribute("aria-pressed") === "true";
                    const navState = isPressed ? "closed" : "open";

                    navigationClickTracking(btnText, null, 1, navState);
                },
            },
            {
                selector: "#main-nav-bookmarks",
                type: "nav-bookmark",
                handler: (e, el) => {
                    const btnText = el.innerText.trim();
                    navigationClickTracking(btnText, "/sruh/bookmarks", 1);
                },
            },
            {
                selector: "#main-nav-close",
                type: "nav-search",
                handler: (e, el) => {
                    const btnText = el.outerText.trim();
                    navigationClickTracking(btnText, null, 1);
                },
            },
            {
                selector: "#main-nav-quiz",
                type: "nav-quiz",
                handler: () => {
                    navigationClickTracking(
                        "Senior Road User Quiz",
                        "/sruh/quiz",
                        1,
                    );
                },
            },
        ];

        navItems.forEach((item) => {
            const elements = mainNav.querySelectorAll(item.selector);

            elements.forEach((el) => {
                if (el.dataset.navTracked) return;
                el.dataset.navTracked = "true";

                el.addEventListener("click", (e) => {
                    item.handler(e, el);
                });
            });
        });

        /*  SUB MENU LINK TRACKING */

        const subNavWrapper = document.querySelector(".main-navigation__aside");
        if (!subNavWrapper) return;

        // Use event delegation to catch all subnav link clicks
        // This works regardless of when the subnav is opened
        if (subNavWrapper.dataset.subNavTrackingSetup) return;
        subNavWrapper.dataset.subNavTrackingSetup = "true";

        subNavWrapper.addEventListener("click", (e) => {
            // Find the clicked link
            const link = e.target.closest(
                ".main-navigation__content-list li a",
            );
            if (!link) return;

            // Only track if the link is within an active menu
            const activeMenu = link.closest(".main-navigation__content.active");
            if (!activeMenu) return;

            const linkText = link.textContent.replace(/\s+/g, " ").trim();
            const linkUrl = link.getAttribute("href") || "";

            navigationClickTracking(linkText, linkUrl, 2);
        });
    }
const TEST_MODE = true; // true = preventDefault for testing, false = production
    function maybePreventDefault(e) {
        if (TEST_MODE) e.preventDefault();
    }
     // usage: maybePreventDefault(e);


//example

   function footerNavTracking() {
        const footerWrapper = document.querySelector(".footer");
        if (!footerWrapper) return;

        footerWrapper.addEventListener("click", (e) => {
            maybePreventDefault(e);
            const { target } = e;

            const link = target.closest(`
                .footer-content__partners-link,
                .footer-content__navigation-link,
                .footer__copyright-section a,
                .footer-site-logo__link
            `);
            if (!link) return;

            const linkurl = link.getAttribute('href') || "";
            const linkTextRaw = link.textContent.trim();
            const linkText = linkTextRaw.replace(/\s+/g, " ").trim() || "";

            if(link.matches('.footer-content__partners-link')){
                gtmPush({
                    event: "navigation_click",
                    navigation_type: "footer_nav",
                    click_text: "our partners",
                    click_url: linkurl,
                    nav_level: 1,
                });
            }

            if(link.matches('.footer-content__navigation-link, .footer__copyright-section a, .footer-site-logo__link')){
                gtmPush({
                    event: "navigation_click",
                    navigation_type: "footer_nav",
                    click_text: linkText,
                    click_url: linkurl,
                    nav_level: 1,
                });
            }
        });
    }
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Creador de Currículum Vitae</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background-color: #f5f7fa;
            color: #333;
            line-height: 1.6;
            padding-bottom: 40px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        
        header {
            text-align: center;
            padding: 30px 0;
            background: linear-gradient(135deg, #2c3e50, #4a6491);
            color: white;
            border-radius: 10px;
            margin-bottom: 30px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        }
        
        h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
        }
        
        .subtitle {
            font-size: 1.1rem;
            opacity: 0.9;
        }
        
        .app-container {
            display: flex;
            flex-wrap: wrap;
            gap: 30px;
        }
        
        .form-section {
            flex: 1;
            min-width: 300px;
            background-color: white;
            border-radius: 10px;
            padding: 25px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
        }
        
        .preview-section {
            flex: 1;
            min-width: 300px;
            background-color: white;
            border-radius: 10px;
            padding: 25px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
        }
        
        h2 {
            color: #2c3e50;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 2px solid #4a6491;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        h2 i {
            color: #4a6491;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #2c3e50;
        }
        
        input, textarea {
            width: 100%;
            padding: 12px 15px;
            border: 1px solid #ddd;
            border-radius: 6px;
            font-size: 1rem;
            transition: border-color 0.3s;
        }
        
        input:focus, textarea:focus {
            outline: none;
            border-color: #4a6491;
        }
        
        textarea {
            min-height: 100px;
            resize: vertical;
        }
        
        .skills-container {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 10px;
        }
        
        .skill-tag {
            background-color: #eef2f7;
            padding: 6px 12px;
            border-radius: 20px;
            display: flex;
            align-items: center;
            gap: 5px;
            font-size: 0.9rem;
        }
        
        .skill-tag .remove-skill {
            cursor: pointer;
            color: #e74c3c;
            font-weight: bold;
        }
        
        .add-skill {
            display: flex;
            gap: 10px;
        }
        
        .add-skill input {
            flex: 1;
        }
        
        .btn {
            background-color: #4a6491;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: 600;
            transition: background-color 0.3s;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }
        
        .btn:hover {
            background-color: #3a5379;
        }
        
        .btn-primary {
            background-color: #2c3e50;
        }
        
        .btn-primary:hover {
            background-color: #1a252f;
        }
        
        .btn-secondary {
            background-color: #3498db;
        }
        
        .btn-secondary:hover {
            background-color: #2980b9;
        }
        
        .btn-danger {
            background-color: #e74c3c;
        }
        
        .btn-danger:hover {
            background-color: #c0392b;
        }
        
        .btn-success {
            background-color: #27ae60;
        }
        
        .btn-success:hover {
            background-color: #219653;
        }
        
        .btn-block {
            display: block;
            width: 100%;
            margin-top: 20px;
            padding: 12px;
        }
        
        .btn-sm {
            padding: 6px 12px;
            font-size: 0.9rem;
        }
        
        /* Estilos para la foto */
        .photo-upload-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 15px;
            margin-bottom: 20px;
        }
        
        .photo-preview {
            width: 150px;
            height: 180px;
            border-radius: 8px;
            border: 3px solid #4a6491;
            overflow: hidden;
            background-color: #f8f9fa;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
        }
        
        .photo-preview img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .photo-placeholder {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            color: #7f8c8d;
            text-align: center;
            padding: 20px;
        }
        
        .photo-placeholder i {
            font-size: 48px;
            margin-bottom: 10px;
            color: #bdc3c7;
        }
        
        .photo-upload-btn {
            position: relative;
            overflow: hidden;
        }
        
        .photo-upload-btn input[type="file"] {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            opacity: 0;
            cursor: pointer;
        }
        
        .photo-actions {
            display: flex;
            gap: 10px;
            margin-top: 10px;
        }
        
        .photo-instructions {
            font-size: 0.85rem;
            color: #666;
            text-align: center;
            margin-top: 5px;
        }
        
        .cv-preview {
            background-color: white;
            min-height: 800px;
            padding: 30px;
            border: 1px solid #eee;
            border-radius: 8px;
            font-size: 0.95rem;
            line-height: 1.5;
        }
        
        /* Encabezado SIN foto (versión anterior) */
        .cv-header-no-photo {
            background-color: #2c3e50;
            color: white;
            padding: 30px;
            border-radius: 8px;
            margin-bottom: 30px;
        }
        
        /* Encabezado CON foto (nueva versión) */
        .cv-header-with-photo {
            background-color: #2c3e50;
            color: white;
            padding: 30px;
            border-radius: 8px;
            margin-bottom: 30px;
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            position: relative;
            min-height: 180px;
        }
        
        .cv-header-content {
            flex: 1;
        }
        
        .cv-photo-container {
            width: 140px;
            height: 160px;
            border-radius: 8px;
            overflow: hidden;
            border: 3px solid rgba(255, 255, 255, 0.3);
            background-color: rgba(255, 255, 255, 0.1);
            display: flex;
            align-items: center;
            justify-content: center;
            margin-left: 20px;
            flex-shrink: 0;
        }
        
        .cv-photo {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .cv-photo-placeholder {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            color: rgba(255, 255, 255, 0.7);
            text-align: center;
            padding: 20px;
            font-size: 0.9rem;
        }
        
        .cv-photo-placeholder i {
            font-size: 36px;
            margin-bottom: 8px;
        }
        
        .cv-name {
            font-size: 2.2rem;
            margin-bottom: 5px;
        }
        
        .cv-title {
            font-size: 1.4rem;
            opacity: 0.9;
            margin-bottom: 15px;
        }
        
        .cv-contact {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin-top: 15px;
        }
        
        .cv-contact-item {
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 0.95rem;
        }
        
        .cv-section {
            margin-bottom: 25px;
        }
        
        .cv-section-title {
            color: #2c3e50;
            border-bottom: 2px solid #4a6491;
            padding-bottom: 5px;
            margin-bottom: 15px;
            font-size: 1.3rem;
        }
        
        .cv-item {
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 1px solid #eee;
        }
        
        .cv-item:last-child {
            border-bottom: none;
        }
        
        .cv-item-title {
            font-weight: 600;
            color: #333;
            margin-bottom: 5px;
            font-size: 1.1rem;
        }
        
        .cv-item-subtitle {
            color: #4a6491;
            font-style: italic;
            margin-bottom: 5px;
        }
        
        .cv-item-dates {
            color: #666;
            font-size: 0.9rem;
            margin-bottom: 8px;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .current-badge {
            background-color: #27ae60;
            color: white;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 0.8rem;
            font-weight: 600;
        }
        
        .cv-skills {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }
        
        .cv-skill {
            background-color: #eef2f7;
            padding: 6px 12px;
            border-radius: 4px;
            font-size: 0.9rem;
        }
        
        .actions {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 30px;
            flex-wrap: wrap;
        }
        
        .instructions {
            background-color: #eef2f7;
            padding: 20px;
            border-radius: 8px;
            margin-top: 30px;
            font-size: 0.95rem;
        }
        
        .instructions h3 {
            margin-bottom: 10px;
            color: #2c3e50;
        }
        
        .instructions ul {
            padding-left: 20px;
        }
        
        .instructions li {
            margin-bottom: 8px;
        }
        
        /* Estilos para la experiencia laboral dinámica */
        .job-entry {
            background-color: #f8f9fa;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            border-left: 4px solid #4a6491;
        }
        
        .job-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }
        
        .job-title {
            font-weight: 600;
            color: #2c3e50;
        }
        
        .current-job-toggle {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 15px;
        }
        
        .toggle-label {
            font-size: 0.9rem;
            color: #666;
        }
        
        .toggle-switch {
            position: relative;
            display: inline-block;
            width: 50px;
            height: 24px;
        }
        
        .toggle-switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        
        .toggle-slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 24px;
        }
        
        .toggle-slider:before {
            position: absolute;
            content: "";
            height: 16px;
            width: 16px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }
        
        input:checked + .toggle-slider {
            background-color: #27ae60;
        }
        
        input:checked + .toggle-slider:before {
            transform: translateX(26px);
        }
        
        .remove-job {
            background-color: transparent;
            border: none;
            color: #e74c3c;
            cursor: pointer;
            font-size: 1.2rem;
            padding: 5px;
        }
        
        .add-job-btn {
            margin-top: 10px;
        }
        
        /* Estilos para el pie de página del PDF */
        .pdf-footer {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            text-align: center;
            font-size: 10pt;
            color: #666;
            padding: 10px;
            background-color: white;
            border-top: 1px solid #eee;
        }
        
        .page-number {
            font-family: Arial, sans-serif;
        }
        
        @media (max-width: 768px) {
            .app-container {
                flex-direction: column;
            }
            
            .cv-preview {
                min-height: auto;
            }
            
            .actions {
                flex-direction: column;
            }
            
            .job-header {
                flex-direction: column;
                align-items: flex-start;
                gap: 10px;
            }
            
            .cv-header-with-photo {
                flex-direction: column;
                align-items: center;
                text-align: center;
                min-height: auto;
            }
            
            .cv-photo-container {
                margin-left: 0;
                margin-bottom: 20px;
                order: -1;
            }
            
            .cv-header-content {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1><i class="fas fa-file-alt"></i> Creador de Currículum Vitae</h1>
            <p class="subtitle">Completa el formulario y genera tu CV profesional en minutos</p>
        </header>
        
        <div class="app-container">
            <!-- Sección del formulario -->
            <section class="form-section">
                <h2><i class="fas fa-edit"></i> Información Personal</h2>
                
                <!-- Subida de foto -->
                <div class="form-group">
                    <label>Foto de Perfil (Opcional)</label>
                    <div class="photo-upload-container">
                        <div class="photo-preview" id="photo-preview">
                            <div class="photo-placeholder" id="photo-placeholder">
                                <i class="fas fa-user-circle"></i>
                                <span>Sin foto</span>
                            </div>
                            <img id="photo-preview-img" style="display: none;">
                        </div>
                        
                        <div class="photo-actions">
                            <button class="btn btn-secondary photo-upload-btn" id="upload-photo-btn">
                                <i class="fas fa-upload"></i> Subir Foto
                                <input type="file" id="photo-input" accept="image/*" style="display: none;">
                            </button>
                            <button class="btn btn-danger" id="remove-photo-btn" style="display: none;">
                                <i class="fas fa-trash"></i> Eliminar
                            </button>
                        </div>
                        
                        <div class="photo-instructions">
                            <p><strong>Opcional:</strong> JPG o PNG, máximo 2MB</p>
                            <p>Con foto: CV moderno | Sin foto: CV clásico</p>
                        </div>
                    </div>
                </div>
                
                <div class="form-group">
                    <label for="name">Nombre Completo</label>
                    <input type="text" id="name" placeholder="Ej: Juan Pérez González">
                </div>
                
                <div class="form-group">
                    <label for="title">Título Profesional</label>
                    <input type="text" id="title" placeholder="Ej: Desarrollador Web Frontend">
                </div>
                
                <div class="form-group">
                    <label for="email">Correo Electrónico</label>
                    <input type="email" id="email" placeholder="Ej: juan.perez@email.com">
                </div>
                
                <div class="form-group">
                    <label for="phone">Teléfono</label>
                    <input type="text" id="phone" placeholder="Ej: +34 612 345 678">
                </div>
                
                <div class="form-group">
                    <label for="location">Ubicación</label>
                    <input type="text" id="location" placeholder="Ej: Madrid, España">
                </div>
                
                <div class="form-group">
                    <label for="summary">Resumen Profesional</label>
                    <textarea id="summary" placeholder="Breve descripción de tu experiencia, habilidades y objetivos profesionales..."></textarea>
                </div>
                
                <h2><i class="fas fa-briefcase"></i> Experiencia Laboral</h2>
                <div id="jobs-container">
                    <!-- Las experiencias laborales se agregarán aquí dinámicamente -->
                </div>
                
                <div class="form-group">
                    <button class="btn btn-secondary add-job-btn" id="add-job-btn">
                        <i class="fas fa-plus"></i> Agregar Experiencia Laboral
                    </button>
                </div>
                
                <h2><i class="fas fa-graduation-cap"></i> Educación</h2>
                
                <div class="form-group">
                    <label for="education1-degree">Título Académico</label>
                    <input type="text" id="education1-degree" placeholder="Ej: Grado en Ingeniería Informática">
                </div>
                
                <div class="form-group">
                    <label for="education1-school">Institución</label>
                    <input type="text" id="education1-school" placeholder="Ej: Universidad Complutense de Madrid">
                </div>
                
                <div class="form-group">
                    <label for="education1-dates">Fechas</label>
                    <input type="text" id="education1-dates" placeholder="Ej: 2016 - 2020">
                </div>
                
                <h2><i class="fas fa-star"></i> Habilidades</h2>
                
                <div class="form-group">
                    <div class="skills-container" id="skills-container">
                        <!-- Las habilidades se agregarán aquí dinámicamente -->
                    </div>
                    <div class="add-skill">
                        <input type="text" id="new-skill" placeholder="Ej: JavaScript, React, HTML/CSS">
                        <button class="btn btn-sm" id="add-skill-btn">Agregar</button>
                    </div>
                </div>
                
                <button class="btn btn-primary btn-block" id="generate-pdf">
                    <i class="fas fa-download"></i> Descargar CV en PDF
                </button>
            </section>
            
            <!-- Sección de vista previa -->
            <section class="preview-section">
                <h2><i class="fas fa-eye"></i> Vista Previa del CV</h2>
                
                <div class="cv-preview" id="cv-preview">
                    <!-- El encabezado se actualizará dinámicamente según si hay foto o no -->
                    <div id="cv-header-container">
                        <!-- Se llenará dinámicamente con JavaScript -->
                    </div>
                    
                    <div class="cv-section">
                        <div class="cv-section-title">Resumen Profesional</div>
                        <div id="cv-summary">Breve descripción de tu experiencia, habilidades y objetivos profesionales.</div>
                    </div>
                    
                    <div class="cv-section">
                        <div class="cv-section-title">Experiencia Laboral</div>
                        <div id="cv-jobs-container">
                            <!-- Las experiencias laborales se mostrarán aquí -->
                            <div class="cv-item">
                                <div class="cv-item-title">Puesto de Trabajo</div>
                                <div class="cv-item-subtitle">Empresa</div>
                                <div class="cv-item-dates">
                                    Fechas
                                    <span class="current-badge">Actual</span>
                                </div>
                                <div>Descripción de responsabilidades y logros en este puesto.</div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="cv-section">
                        <div class="cv-section-title">Educación</div>
                        <div class="cv-item">
                            <div class="cv-item-title" id="cv-education1-degree">Título Académico</div>
                            <div class="cv-item-subtitle" id="cv-education1-school">Institución</div>
                            <div class="cv-item-dates" id="cv-education1-dates">Fechas</div>
                        </div>
                    </div>
                    
                    <div class="cv-section">
                        <div class="cv-section-title">Habilidades</div>
                        <div class="cv-skills" id="cv-skills">
                            <div class="cv-skill">Ejemplo de habilidad</div>
                            <div class="cv-skill">Otra habilidad</div>
                            <div class="cv-skill">Habilidad técnica</div>
                        </div>
                    </div>
                </div>
                
                <div class="actions">
                    <button class="btn" id="reset-form">
                        <i class="fas fa-redo"></i> Reiniciar Formulario
                    </button>
                    <button class="btn" id="print-cv">
                        <i class="fas fa-print"></i> Imprimir CV
                    </button>
                </div>
                
                <div class="instructions">
                    <h3>Instrucciones:</h3>
                    <ul>
                        <li><strong>Foto opcional:</strong> Con foto tendrás un CV moderno, sin foto un CV clásico.</li>
                        <li>Completa todos los campos del formulario.</li>
                        <li>Agrega tus experiencias laborales con el botón "Agregar Experiencia Laboral".</li>
                        <li>Marca como "Trabajo Actual" si es tu empleo actual.</li>
                        <li>La vista previa se actualizará automáticamente.</li>
                        <li>Agrega tus habilidades una por una.</li>
                        <li>Haz clic en "Descargar CV en PDF" para guardar tu currículum.</li>
                        <li>Usa "Imprimir CV" si prefieres imprimirlo directamente.</li>
                    </ul>
                </div>
            </section>
        </div>
    </div>

    <!-- Incluir html2pdf -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
    
    <script>
        // Elementos del formulario
        const formInputs = {
            name: document.getElementById('name'),
            title: document.getElementById('title'),
            email: document.getElementById('email'),
            phone: document.getElementById('phone'),
            location: document.getElementById('location'),
            summary: document.getElementById('summary'),
            education1Degree: document.getElementById('education1-degree'),
            education1School: document.getElementById('education1-school'),
            education1Dates: document.getElementById('education1-dates'),
            newSkill: document.getElementById('new-skill')
        };
        
        // Elementos de vista previa
        const previewElements = {
            name: document.getElementById('cv-name'),
            title: document.getElementById('cv-title'),
            email: document.getElementById('cv-email'),
            phone: document.getElementById('cv-phone'),
            location: document.getElementById('cv-location'),
            summary: document.getElementById('cv-summary'),
            education1Degree: document.getElementById('cv-education1-degree'),
            education1School: document.getElementById('cv-education1-school'),
            education1Dates: document.getElementById('cv-education1-dates'),
            skills: document.getElementById('cv-skills'),
            jobsContainer: document.getElementById('cv-jobs-container'),
            headerContainer: document.getElementById('cv-header-container')
        };
        
        // Elementos de foto
        const photoInput = document.getElementById('photo-input');
        const photoPreview = document.getElementById('photo-preview-img');
        const photoPlaceholder = document.getElementById('photo-placeholder');
        const uploadPhotoBtn = document.getElementById('upload-photo-btn');
        const removePhotoBtn = document.getElementById('remove-photo-btn');
        
        // Elementos de habilidades
        const skillsContainer = document.getElementById('skills-container');
        const addSkillBtn = document.getElementById('add-skill-btn');
        const cvSkillsContainer = document.getElementById('cv-skills');
        
        // Elementos de experiencia laboral
        const jobsContainer = document.getElementById('jobs-container');
        const addJobBtn = document.getElementById('add-job-btn');
        
        // Botones de acción
        const generatePdfBtn = document.getElementById('generate-pdf');
        const resetFormBtn = document.getElementById('reset-form');
        const printCvBtn = document.getElementById('print-cv');
        
        // Almacenar habilidades
        let skills = ['JavaScript', 'HTML/CSS', 'React', 'Git'];
        
        // Almacenar experiencias laborales
        let jobs = [
            {
                id: 1,
                title: 'Desarrollador Frontend',
                company: 'Tech Solutions S.A.',
                dates: 'Enero 2020 - Presente',
                description: 'Desarrollo de aplicaciones web utilizando React, HTML5 y CSS3. Colaboración en equipos ágiles.',
                current: true
            },
            {
                id: 2,
                title: 'Desarrollador Web Junior',
                company: 'Digital Agency',
                dates: 'Junio 2018 - Diciembre 2019',
                description: 'Creación de sitios web responsivos y mantenimiento de sitios existentes.',
                current: false
            }
        ];
        
        // Almacenar foto (como Data URL)
        let userPhoto = null;
        
        // Función para actualizar el encabezado según si hay foto o no
        function updateCVHeader() {
            if (userPhoto) {
                // Con foto: usar diseño con foto
                previewElements.headerContainer.innerHTML = `
                    <div class="cv-header-with-photo">
                        <div class="cv-header-content">
                            <div class="cv-name">${formInputs.name.value || 'Nombre Completo'}</div>
                            <div class="cv-title">${formInputs.title.value || 'Título Profesional'}</div>
                            <div class="cv-contact">
                                <div class="cv-contact-item">
                                    <i class="fas fa-envelope"></i> ${formInputs.email.value || 'correo@ejemplo.com'}
                                </div>
                                <div class="cv-contact-item">
                                    <i class="fas fa-phone"></i> ${formInputs.phone.value || '+34 612 345 678'}
                                </div>
                                <div class="cv-contact-item">
                                    <i class="fas fa-map-marker-alt"></i> ${formInputs.location.value || 'Ciudad, País'}
                                </div>
                            </div>
                        </div>
                        
                        <div class="cv-photo-container">
                            <img src="${userPhoto}" class="cv-photo">
                        </div>
                    </div>
                `;
            } else {
                // Sin foto: usar diseño clásico (como la versión anterior)
                previewElements.headerContainer.innerHTML = `
                    <div class="cv-header-no-photo">
                        <div class="cv-name">${formInputs.name.value || 'Nombre Completo'}</div>
                        <div class="cv-title">${formInputs.title.value || 'Título Profesional'}</div>
                        <div class="cv-contact">
                            <div class="cv-contact-item">
                                <i class="fas fa-envelope"></i> ${formInputs.email.value || 'correo@ejemplo.com'}
                            </div>
                            <div class="cv-contact-item">
                                <i class="fas fa-phone"></i> ${formInputs.phone.value || '+34 612 345 678'}
                            </div>
                            <div class="cv-contact-item">
                                <i class="fas fa-map-marker-alt"></i> ${formInputs.location.value || 'Ciudad, País'}
                            </div>
                        </div>
                    </div>
                `;
            }
        }
        
        // Inicializar foto
        function initializePhoto() {
            // Agregar evento al botón de subida personalizado
            uploadPhotoBtn.addEventListener('click', function() {
                photoInput.click();
            });
            
            // Manejar selección de archivo
            photoInput.addEventListener('change', handlePhotoUpload);
            
            // Manejar eliminación de foto
            removePhotoBtn.addEventListener('click', removePhoto);
        }
        
        // Manejar subida de foto
        function handlePhotoUpload(event) {
            const file = event.target.files[0];
            if (!file) return;
            
            // Validar tipo de archivo
            if (!file.type.match('image.*')) {
                alert('Por favor, selecciona un archivo de imagen (JPG, PNG, etc.)');
                return;
            }
            
            // Validar tamaño (máximo 2MB)
            if (file.size > 2 * 1024 * 1024) {
                alert('La imagen es demasiado grande. El tamaño máximo es 2MB.');
                return;
            }
            
            const reader = new FileReader();
            
            reader.onload = function(e) {
                userPhoto = e.target.result;
                
                // Mostrar vista previa en el formulario
                photoPreview.src = userPhoto;
                photoPreview.style.display = 'block';
                photoPlaceholder.style.display = 'none';
                
                // Mostrar botón de eliminar
                removePhotoBtn.style.display = 'block';
                
                // Actualizar encabezado del CV
                updateCVHeader();
            };
            
            reader.readAsDataURL(file);
        }
        
        // Eliminar foto
        function removePhoto() {
            userPhoto = null;
            
            // Ocultar vista previa en el formulario
            photoPreview.style.display = 'none';
            photoPlaceholder.style.display = 'flex';
            
            // Ocultar botón de eliminar
            removePhotoBtn.style.display = 'none';
            
            // Limpiar input de archivo
            photoInput.value = '';
            
            // Actualizar encabezado del CV
            updateCVHeader();
        }
        
        // Inicializar experiencias laborales
        function initializeJobs() {
            jobsContainer.innerHTML = '';
            jobs.forEach(job => {
                addJobToForm(job);
            });
            updateJobsPreview();
        }
        
        // Agregar experiencia laboral al formulario
        function addJobToForm(job = null) {
            const jobId = job ? job.id : Date.now();
            const jobTitle = job ? job.title : '';
            const jobCompany = job ? job.company : '';
            const jobDates = job ? job.dates : '';
            const jobDescription = job ? job.description : '';
            const isCurrent = job ? job.current : false;
            
            const jobEntry = document.createElement('div');
            jobEntry.className = 'job-entry';
            jobEntry.id = `job-${jobId}`;
            
            jobEntry.innerHTML = `
                <div class="job-header">
                    <div class="job-title">Experiencia Laboral</div>
                    <button type="button" class="remove-job" data-job-id="${jobId}">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
                
                <div class="current-job-toggle">
                    <span class="toggle-label">¿Es tu trabajo actual?</span>
                    <label class="toggle-switch">
                        <input type="checkbox" class="current-job-checkbox" ${isCurrent ? 'checked' : ''} data-job-id="${jobId}">
                        <span class="toggle-slider"></span>
                    </label>
                </div>
                
                <div class="form-group">
                    <label for="job-title-${jobId}">Puesto de Trabajo</label>
                    <input type="text" id="job-title-${jobId}" class="job-title-input" 
                           placeholder="Ej: Desarrollador Frontend" value="${jobTitle}">
                </div>
                
                <div class="form-group">
                    <label for="job-company-${jobId}">Empresa</label>
                    <input type="text" id="job-company-${jobId}" class="job-company-input" 
                           placeholder="Ej: Tech Solutions S.A." value="${jobCompany}">
                </div>
                
                <div class="form-group">
                    <label for="job-dates-${jobId}">Fechas</label>
                    <input type="text" id="job-dates-${jobId}" class="job-dates-input" 
                           placeholder="Ej: Enero 2020 - Presente" value="${jobDates}">
                </div>
                
                <div class="form-group">
                    <label for="job-description-${jobId}">Descripción</label>
                    <textarea id="job-description-${jobId}" class="job-description-input" 
                              placeholder="Describe tus responsabilidades y logros en este puesto...">${jobDescription}</textarea>
                </div>
            `;
            
            jobsContainer.appendChild(jobEntry);
            
            // Añadir eventos a los campos de este trabajo
            const titleInput = jobEntry.querySelector('.job-title-input');
            const companyInput = jobEntry.querySelector('.job-company-input');
            const datesInput = jobEntry.querySelector('.job-dates-input');
            const descriptionInput = jobEntry.querySelector('.job-description-input');
            const currentCheckbox = jobEntry.querySelector('.current-job-checkbox');
            const removeBtn = jobEntry.querySelector('.remove-job');
            
            // Actualizar el array de trabajos cuando cambien los inputs
            const updateJobInArray = () => {
                const jobIndex = jobs.findIndex(j => j.id === jobId);
                
                if (jobIndex === -1) {
                    // Nuevo trabajo
                    jobs.push({
                        id: jobId,
                        title: titleInput.value,
                        company: companyInput.value,
                        dates: datesInput.value,
                        description: descriptionInput.value,
                        current: currentCheckbox.checked
                    });
                } else {
                    // Actualizar trabajo existente
                    jobs[jobIndex] = {
                        ...jobs[jobIndex],
                        title: titleInput.value,
                        company: companyInput.value,
                        dates: datesInput.value,
                        description: descriptionInput.value,
                        current: currentCheckbox.checked
                    };
                }
                
                updateJobsPreview();
            };
            
            titleInput.addEventListener('input', updateJobInArray);
            companyInput.addEventListener('input', updateJobInArray);
            datesInput.addEventListener('input', updateJobInArray);
            descriptionInput.addEventListener('input', updateJobInArray);
            currentCheckbox.addEventListener('change', updateJobInArray);
            
            // Eliminar trabajo
            removeBtn.addEventListener('click', function() {
                if (jobs.length <= 1) {
                    alert('Debes tener al menos una experiencia laboral.');
                    return;
                }
                
                if (confirm('¿Estás seguro de que quieres eliminar esta experiencia laboral?')) {
                    jobs = jobs.filter(j => j.id !== jobId);
                    jobEntry.remove();
                    updateJobsPreview();
                }
            });
            
            // Si es un trabajo nuevo, agregarlo al array
            if (!job) {
                jobs.push({
                    id: jobId,
                    title: '',
                    company: '',
                    dates: '',
                    description: '',
                    current: false
                });
            }
        }
        
        // Actualizar vista previa de experiencias laborales
        function updateJobsPreview() {
            previewElements.jobsContainer.innerHTML = '';
            
            // Ordenar trabajos: primero los actuales, luego los anteriores
            const sortedJobs = [...jobs].sort((a, b) => {
                if (a.current && !b.current) return -1;
                if (!a.current && b.current) return 1;
                return 0;
            });
            
            sortedJobs.forEach(job => {
                if (job.title || job.company || job.dates || job.description) {
                    const jobElement = document.createElement('div');
                    jobElement.className = 'cv-item';
                    
                    jobElement.innerHTML = `
                        <div class="cv-item-title">${job.title || 'Puesto de Trabajo'}</div>
                        <div class="cv-item-subtitle">${job.company || 'Empresa'}</div>
                        <div class="cv-item-dates">
                            ${job.dates || 'Fechas'}
                            ${job.current ? '<span class="current-badge">Actual</span>' : ''}
                        </div>
                        <div>${job.description || 'Descripción de responsabilidades y logros en este puesto.'}</div>
                    `;
                    
                    previewElements.jobsContainer.appendChild(jobElement);
                }
            });
            
            // Si no hay trabajos, mostrar un placeholder
            if (previewElements.jobsContainer.children.length === 0) {
                const placeholder = document.createElement('div');
                placeholder.className = 'cv-item';
                placeholder.innerHTML = `
                    <div class="cv-item-title">Puesto de Trabajo</div>
                    <div class="cv-item-subtitle">Empresa</div>
                    <div class="cv-item-dates">
                        Fechas
                        <span class="current-badge">Actual</span>
                    </div>
                    <div>Descripción de responsabilidades y logros en este puesto.</div>
                `;
                previewElements.jobsContainer.appendChild(placeholder);
            }
        }
        
        // Inicializar habilidades
        function initializeSkills() {
            skills.forEach(skill => addSkillToContainers(skill));
        }
        
        // Agregar habilidad a ambos contenedores
        function addSkillToContainers(skill) {
            // Agregar al formulario
            const skillTag = document.createElement('div');
            skillTag.className = 'skill-tag';
            skillTag.innerHTML = `
                ${skill}
                <span class="remove-skill" data-skill="${skill}">×</span>
            `;
            skillsContainer.appendChild(skillTag);
            
            // Agregar a la vista previa
            const cvSkill = document.createElement('div');
            cvSkill.className = 'cv-skill';
            cvSkill.textContent = skill;
            cvSkillsContainer.appendChild(cvSkill);
            
            // Añadir evento para eliminar habilidad
            skillTag.querySelector('.remove-skill').addEventListener('click', function() {
                const skillToRemove = this.getAttribute('data-skill');
                skills = skills.filter(s => s !== skillToRemove);
                updateSkillsDisplay();
            });
        }
        
        // Actualizar visualización de habilidades
        function updateSkillsDisplay() {
            // Limpiar contenedores
            skillsContainer.innerHTML = '';
            cvSkillsContainer.innerHTML = '';
            
            // Volver a agregar todas las habilidades
            skills.forEach(skill => addSkillToContainers(skill));
        }
        
        // Actualizar vista previa en tiempo real
        function updatePreview() {
            // Información personal
            updateCVHeader(); // Actualizar encabezado según si hay foto o no
            
            previewElements.summary.textContent = formInputs.summary.value || 'Breve descripción de tu experiencia, habilidades y objetivos profesionales.';
            
            // Educación
            previewElements.education1Degree.textContent = formInputs.education1Degree.value || 'Título Académico';
            previewElements.education1School.textContent = formInputs.education1School.value || 'Institución';
            previewElements.education1Dates.textContent = formInputs.education1Dates.value || 'Fechas';
            
            // Experiencias laborales ya se actualizan por separado
        }
        
        // Añadir eventos de entrada a todos los campos del formulario
        Object.values(formInputs).forEach(input => {
            if (input && input.tagName !== 'BUTTON') {
                input.addEventListener('input', updatePreview);
            }
        });
        
        // Añadir nueva habilidad
        addSkillBtn.addEventListener('click', function() {
            const newSkill = formInputs.newSkill.value.trim();
            if (newSkill && !skills.includes(newSkill)) {
                skills.push(newSkill);
                updateSkillsDisplay();
                formInputs.newSkill.value = '';
            }
        });
        
        // Permitir agregar habilidad con Enter
        formInputs.newSkill.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                addSkillBtn.click();
            }
        });
        
        // Añadir nueva experiencia laboral
        addJobBtn.addEventListener('click', function() {
            addJobToForm();
        });
        
        // Crear CV limpio para PDF con pie de página personalizado
        function createCleanCVForPDF() {
            const cleanCV = document.createElement('div');
            cleanCV.className = 'cv-pdf-clean';
            
            // Ordenar trabajos: primero los actuales, luego los anteriores
            const sortedJobs = [...jobs].sort((a, b) => {
                if (a.current && !b.current) return -1;
                if (!a.current && b.current) return 1;
                return 0;
            });
            
            // Filtrar trabajos que tengan al menos un campo completado
            const filteredJobs = sortedJobs.filter(job => 
                job.title || job.company || job.dates || job.description
            );
            
            // Crear encabezado según si hay foto o no
            let headerHTML = '';
            if (userPhoto) {
                // Con foto: diseño moderno
                headerHTML = `
                    <div style="background-color: #2c3e50; color: white; padding: 30px; border-radius: 8px; margin-bottom: 30px; display: flex; justify-content: space-between; align-items: flex-start;">
                        <div style="flex: 1;">
                            <div style="font-size: 28pt; font-weight: bold; margin-bottom: 5px;">${formInputs.name.value || 'Nombre Completo'}</div>
                            <div style="font-size: 18pt; opacity: 0.9; margin-bottom: 15px;">${formInputs.title.value || 'Título Profesional'}</div>
                            <div style="display: flex; flex-wrap: wrap; gap: 20px; margin-top: 15px;">
                                <div style="display: flex; align-items: center; gap: 8px; font-size: 11pt;">
                                    <i class="fas fa-envelope"></i> ${formInputs.email.value || 'correo@ejemplo.com'}
                                </div>
                                <div style="display: flex; align-items: center; gap: 8px; font-size: 11pt;">
                                    <i class="fas fa-phone"></i> ${formInputs.phone.value || '+34 612 345 678'}
                                </div>
                                <div style="display: flex; align-items: center; gap: 8px; font-size: 11pt;">
                                    <i class="fas fa-map-marker-alt"></i> ${formInputs.location.value || 'Ciudad, País'}
                                </div>
                            </div>
                        </div>
                        
                        <div style="width: 120px; height: 150px; border-radius: 8px; overflow: hidden; border: 3px solid rgba(255, 255, 255, 0.3); margin-left: 20px; flex-shrink: 0;">
                            <img src="${userPhoto}" style="width: 100%; height: 100%; object-fit: cover;">
                        </div>
                    </div>
                `;
            } else {
                // Sin foto: diseño clásico (como versión anterior)
                headerHTML = `
                    <div style="background-color: #2c3e50; color: white; padding: 30px; border-radius: 8px; margin-bottom: 30px;">
                        <div style="font-size: 28pt; font-weight: bold; margin-bottom: 5px;">${formInputs.name.value || 'Nombre Completo'}</div>
                        <div style="font-size: 18pt; opacity: 0.9; margin-bottom: 15px;">${formInputs.title.value || 'Título Profesional'}</div>
                        <div style="display: flex; flex-wrap: wrap; gap: 20px; margin-top: 15px;">
                            <div style="display: flex; align-items: center; gap: 8px; font-size: 11pt;">
                                <i class="fas fa-envelope"></i> ${formInputs.email.value || 'correo@ejemplo.com'}
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; font-size: 11pt;">
                                <i class="fas fa-phone"></i> ${formInputs.phone.value || '+34 612 345 678'}
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; font-size: 11pt;">
                                <i class="fas fa-map-marker-alt"></i> ${formInputs.location.value || 'Ciudad, País'}
                            </div>
                        </div>
                    </div>
                `;
            }
            
            cleanCV.innerHTML = `
                ${headerHTML}
                
                <div class="cv-pdf-section">
                    <div class="cv-pdf-section-title">Resumen Profesional</div>
                    <div>${formInputs.summary.value || 'Breve descripción de tu experiencia, habilidades y objetivos profesionales.'}</div>
                </div>
                
                <div class="cv-pdf-section">
                    <div class="cv-pdf-section-title">Experiencia Laboral</div>
                    ${filteredJobs.map(job => `
                        <div class="cv-pdf-item">
                            <div class="cv-pdf-item-title">${job.title || 'Puesto de Trabajo'}</div>
                            <div class="cv-pdf-item-subtitle">${job.company || 'Empresa'}</div>
                            <div class="cv-pdf-item-dates">
                                ${job.dates || 'Fechas'}
                                ${job.current ? '<span style="background-color: #27ae60; color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.8rem; margin-left: 8px;">Actual</span>' : ''}
                            </div>
                            <div>${job.description || 'Descripción de responsabilidades y logros en este puesto.'}</div>
                        </div>
                    `).join('')}
                </div>
                
                <div class="cv-pdf-section">
                    <div class="cv-pdf-section-title">Educación</div>
                    <div class="cv-pdf-item">
                        <div class="cv-pdf-item-title">${formInputs.education1Degree.value || 'Título Académico'}</div>
                        <div class="cv-pdf-item-subtitle">${formInputs.education1School.value || 'Institución'}</div>
                        <div class="cv-pdf-item-dates">${formInputs.education1Dates.value || 'Fechas'}</div>
                    </div>
                </div>
                
                <div class="cv-pdf-section">
                    <div class="cv-pdf-section-title">Habilidades</div>
                    <div class="cv-pdf-skills">
                        ${skills.map(skill => `<div class="cv-pdf-skill">${skill}</div>`).join('')}
                    </div>
                </div>
                
                <!-- Pie de página para el PDF -->
                <div class="pdf-footer">
                    <div class="page-number">Página <span class="page"></span> de <span class="total"></span></div>
                </div>
            `;
            
            // Agregar estilos CSS para el PDF
            const style = document.createElement('style');
            style.textContent = `
                .cv-pdf-clean {
                    width: 100%;
                    background-color: white;
                    padding: 40px;
                    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                    color: #333;
                    line-height: 1.6;
                    position: relative;
                    min-height: 100vh;
                }
                
                .cv-pdf-section {
                    margin-bottom: 25px;
                }
                
                .cv-pdf-section-title {
                    color: #2c3e50;
                    border-bottom: 2px solid #4a6491;
                    padding-bottom: 5px;
                    margin-bottom: 15px;
                    font-size: 16pt;
                    font-weight: bold;
                }
                
                .cv-pdf-item {
                    margin-bottom: 15px;
                    padding-bottom: 15px;
                    border-bottom: 1px solid #eee;
                }
                
                .cv-pdf-item:last-child {
                    border-bottom: none;
                }
                
                .cv-pdf-item-title {
                    font-weight: 600;
                    color: #333;
                    margin-bottom: 5px;
                    font-size: 12pt;
                }
                
                .cv-pdf-item-subtitle {
                    color: #4a6491;
                    font-style: italic;
                    margin-bottom: 5px;
                    font-size: 11pt;
                }
                
                .cv-pdf-item-dates {
                    color: #666;
                    font-size: 10pt;
                    margin-bottom: 8px;
                    display: flex;
                    align-items: center;
                }
                
                .cv-pdf-skills {
                    display: flex;
                    flex-wrap: wrap;
                    gap: 10px;
                    margin-bottom: 60px;
                }
                
                .cv-pdf-skill {
                    background-color: #eef2f7;
                    padding: 6px 12px;
                    border-radius: 4px;
                    font-size: 10pt;
                }
                
                .pdf-footer {
                    position: fixed;
                    bottom: 0;
                    left: 0;
                    right: 0;
                    text-align: center;
                    font-size: 10pt;
                    color: #666;
                    padding: 10px;
                    background-color: white;
                    border-top: 1px solid #eee;
                    height: 40px;
                }
                
                .page-number {
                    font-family: Arial, sans-serif;
                }
            `;
            
            cleanCV.appendChild(style);
            return cleanCV;
        }
        
        // Generar PDF limpio con numeración de páginas personalizada
        generatePdfBtn.addEventListener('click', async function() {
            const cleanCV = createCleanCVForPDF();
            
            // Opciones para html2pdf
            const options = {
                margin: [0.5, 0.8, 0.5, 0.8], // [top, right, bottom, left]
                filename: `CV_${formInputs.name.value || 'Mi_CV'}.pdf`,
                image: { type: 'jpeg', quality: 0.98 },
                html2canvas: { 
                    scale: 2,
                    useCORS: true,
                    logging: false,
                    windowWidth: 794,
                    windowHeight: 1123
                },
                jsPDF: { 
                    unit: 'mm', 
                    format: 'a4', 
                    orientation: 'portrait',
                    putTotalPages: '{total_pages_count_string}'
                },
                pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
            };
            
            // Configurar el pie de página con números de página
            const worker = html2pdf().set(options).from(cleanCV);
            
            worker.toPdf().get('pdf').then(function(pdf) {
                const totalPages = pdf.internal.getNumberOfPages();
                
                for (let i = 1; i <= totalPages; i++) {
                    pdf.setPage(i);
                    pdf.setFontSize(10);
                    pdf.setFont("helvetica", "normal");
                    pdf.text(`Página ${i} de ${totalPages}`, pdf.internal.pageSize.width / 2, 
                            pdf.internal.pageSize.height - 10, {align: 'center'});
                }
            }).save();
        });
        
        // Imprimir CV limpio
        printCvBtn.addEventListener('click', function() {
            const cleanCV = createCleanCVForPDF();
            
            // Crear ventana de impresión
            const printWindow = window.open('', '_blank');
            printWindow.document.write(`
                <!DOCTYPE html>
                <html>
                <head>
                    <title>Curriculum Vitae - ${formInputs.name.value || 'Mi CV'}</title>
                    <style>
                        body {
                            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                            color: #333;
                            line-height: 1.6;
                            margin: 0;
                            padding: 20px;
                        }
                        
                        .cv-pdf-header {
                            background-color: #2c3e50;
                            color: white;
                            padding: 30px;
                            border-radius: 8px;
                            margin-bottom: 30px;
                        }
                        
                        .cv-pdf-header-with-photo {
                            display: flex;
                            justify-content: space-between;
                            align-items: flex-start;
                        }
                        
                        .cv-pdf-name {
                            font-size: 28pt;
                            margin-bottom: 5px;
                            font-weight: bold;
                        }
                        
                        .cv-pdf-title {
                            font-size: 18pt;
                            opacity: 0.9;
                            margin-bottom: 15px;
                        }
                        
                        .cv-pdf-contact {
                            display: flex;
                            flex-wrap: wrap;
                            gap: 20px;
                            margin-top: 15px;
                        }
                        
                        .cv-pdf-contact-item {
                            display: flex;
                            align-items: center;
                            gap: 8px;
                            font-size: 11pt;
                        }
                        
                        .cv-photo-container {
                            width: 120px;
                            height: 150px;
                            border-radius: 8px;
                            overflow: hidden;
                            border: 3px solid rgba(255, 255, 255, 0.3);
                            margin-left: 20px;
                        }
                        
                        .cv-photo-container img {
                            width: 100%;
                            height: 100%;
                            object-fit: cover;
                        }
                        
                        .cv-pdf-section {
                            margin-bottom: 25px;
                        }
                        
                        .cv-pdf-section-title {
                            color: #2c3e50;
                            border-bottom: 2px solid #4a6491;
                            padding-bottom: 5px;
                            margin-bottom: 15px;
                            font-size: 16pt;
                            font-weight: bold;
                        }
                        
                        .cv-pdf-item {
                            margin-bottom: 15px;
                            padding-bottom: 15px;
                            border-bottom: 1px solid #eee;
                        }
                        
                        .cv-pdf-item:last-child {
                            border-bottom: none;
                        }
                        
                        .cv-pdf-item-title {
                            font-weight: 600;
                            color: #333;
                            margin-bottom: 5px;
                            font-size: 12pt;
                        }
                        
                        .cv-pdf-item-subtitle {
                            color: #4a6491;
                            font-style: italic;
                            margin-bottom: 5px;
                            font-size: 11pt;
                        }
                        
                        .cv-pdf-item-dates {
                            color: #666;
                            font-size: 10pt;
                            margin-bottom: 8px;
                            display: flex;
                            align-items: center;
                        }
                        
                        .cv-pdf-skills {
                            display: flex;
                            flex-wrap: wrap;
                            gap: 10px;
                        }
                        
                        .cv-pdf-skill {
                            background-color: #eef2f7;
                            padding: 6px 12px;
                            border-radius: 4px;
                            font-size: 10pt;
                        }
                        
                        @media print {
                            body {
                                padding: 0;
                            }
                            
                            @page {
                                margin: 20mm;
                                @bottom-center {
                                    content: "Página " counter(page) " de " counter(pages);
                                    font-family: Arial, sans-serif;
                                    font-size: 10pt;
                                    color: #666;
                                }
                            }
                        }
                    </style>
                </head>
                <body>
                    ${cleanCV.innerHTML}
                </body>
                </html>
            `);
            
            printWindow.document.close();
            printWindow.focus();
            
            setTimeout(() => {
                printWindow.print();
                setTimeout(() => {
                    printWindow.close();
                }, 500);
            }, 500);
        });
        
        // Reiniciar formulario
        resetFormBtn.addEventListener('click', function() {
            if (confirm('¿Estás seguro de que quieres reiniciar el formulario? Se perderán todos los datos.')) {
                // Limpiar campos del formulario
                Object.values(formInputs).forEach(input => {
                    if (input && input.tagName !== 'BUTTON') {
                        input.value = '';
                    }
                });
                
                // Restablecer habilidades
                skills = ['JavaScript', 'HTML/CSS', 'React', 'Git'];
                updateSkillsDisplay();
                
                // Restablecer experiencias laborales
                jobs = [
                    {
                        id: 1,
                        title: '',
                        company: '',
                        dates: '',
                        description: '',
                        current: false
                    }
                ];
                initializeJobs();
                
                // Eliminar foto si existe
                if (userPhoto) {
                    removePhoto();
                }
                
                // Actualizar vista previa
                updatePreview();
            }
        });
        
        // Datos de ejemplo para probar
        function loadSampleData() {
            // Solo cargar si no hay datos en el formulario
            if (!formInputs.name.value) {
                formInputs.name.value = 'María López García';
                formInputs.title.value = 'Desarrolladora Full Stack';
                formInputs.email.value = 'maria.lopez@email.com';
                formInputs.phone.value = '+34 634 567 890';
                formInputs.location.value = 'Barcelona, España';
                formInputs.summary.value = 'Desarrolladora con 5 años de experiencia en el desarrollo de aplicaciones web. Especializada en JavaScript, React y Node.js. Apasionada por crear soluciones eficientes y escalables.';
                formInputs.education1Degree.value = 'Grado en Ingeniería Informática';
                formInputs.education1School.value = 'Universidad Politécnica de Cataluña';
                formInputs.education1Dates.value = '2015 - 2019';
                
                // Actualizar vista previa
                updatePreview();
            }
        }
        
        // Inicializar la aplicación
        function init() {
            initializePhoto();
            initializeSkills();
            initializeJobs();
            updatePreview();
            loadSampleData();
        }
        
        // Iniciar cuando el DOM esté listo
        document.addEventListener('DOMContentLoaded', init);
    </script>
</body>
</html>
=SI(ESTVIDE(A1); "ta formule"; A1)
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":sunshine: :x-connect: Boost Days: What's on this week :x-connect: :sunshine:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Good morning Melbourne and hope you all had a fab weekend! :sunshine: \n\n Please see below for what's on this week! "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-21: Wednesday, 21st January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee:  :donutss: *Xero Café* – A selection of Donuts \n :coffee:*Barista Special* – Rod Laver Latte :tennis: \n :spaghetti:Join us at *12.00pm* for some * Delicious Pasta from Pasta Prego* in the Wominjeka Breakout Space on Level 3. Check out the:thread:"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-22: Thursday, 22nd January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Xero Cafe*: A selection of Donuts \n :coffee: *Barista Special* – Rod Laver Latte \n :Breakfast: Join us at *8.30am -10.30am* for a * Breakfast Buffet* in the Wominjeka Breakout Space in the Level 3 breakout space."
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": " What else? :heart:  \n\nStay tuned to this channel, and make sure you’re subscribed to the <https://calendar.google.com/calendar/u/0/r?cid=Y19xczkyMjk5ZGlsODJzMjA4aGt1b3RnM2t1MEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t /|*Melbourne Social Calendar*> for all upcoming events. \n\n :tennis: :pingpong: In celebration of the Australian Open, On *Friday 30th January*, we are inviting 20 teams to compete in our own Xero Melbourne Open :melbourne:. Yes, we are hosting a Ping Pong competition during our Social at 4pm in the Wominjeka Breakout Space. Please sign up in the :thread: for a chance to win some official AO merchandise. \n\n DON'T MISS OUT! :yay:\t\t"
			}
		}
	]
}
 // page view counter
        function incrementPageViewCount() {
            const key = "page_view_count";
            const count = Number(sessionStorage.getItem(key)) || 0;
            const newCount = count + 1;
            sessionStorage.setItem(key, newCount);
            return newCount;
        }
import $, { contains } from 'jquery';

class Property {
  constructor(element) {
    this.$element = $(element);
    this.$tabs = this.$element.find(".property--tab li");
    this.$tabsContent = this.$element.find(".property--main-row");
    this.init();
  }

  init() {
    this.$tabs.first().addClass("active");
    this.$tabsContent.hide();
    this.$tabsContent.first().show();

    this.$tabs.click((e) => {
      e.preventDefault();
      if ($(e.currentTarget).hasClass("active")) {
        return;
      }
      this.$tabs.removeClass("active");
      $(e.currentTarget).addClass("active");
      this.$tabsContent.hide();

      var activeTab = $(e.currentTarget).find("a").attr("href");
      $(activeTab).fadeIn(700);
      return false;
    });
  }
}

$('[data-property]').each((index, element) => new Property(element));
A reliable approach is to work with a development team that delivers cryptocurrency exchange software built for security, speed, and operational stability. The right solution should support centralized, decentralized, or hybrid exchange models and adapt to specific business and market requirements. Features such as robust security controls, fast transaction processing, real-time updates, and comprehensive management tools are essential for serving both beginner and professional traders. Softean’s cryptocurrency exchange development follow this approach, enabling businesses to scale confidently while maintaining trust, performance, and long-term reliability >> https://www.softean.com/cryptocurrency-exchange-development  
function getRandomChar(charset: string) {
  const index = Math.floor(Math.random() * charset.length);
  return charset[index] ?? "";
}

function generateRandomString(length: number, charset: string) {
  let result = "";
  for (let i = 0; i < length; i += 1) {
    result += getRandomChar(charset);
  }
  return result;
}
// px -> rem 转换
const pxToRem = (px: number, base: number) => {
  if (base === 0) return "0";
  return (px / base).toFixed(4).replace(/\.?0+$/, "");
};

// rem -> px 转换
const remToPx = (rem: number, base: number) => {
  return (rem * base).toFixed(2).replace(/\.?0+$/, "");
};
Within the vast body of industry, where structures stand on the shoulders of strength and machinery operates on the foundation of reliability, small components play a key role that might go unnoticed at first glance. Among these silent heroes, the Grade 8.8 bolt holds a lofty and unparalleled position. This name, familiar in the Iranian market vernacular, in fact narrates a story of steel, carbon, and tireless resistance. But the fundamental question is: What differentiates this seemingly simple piece from ordinary bolts? Why has purchasing  <a href="https://screw.full-design.com/grade-8-8-bolt-the-steel-elixir-in-the-fastening-industry-81814969" onclick="window.open(this.href, '', 'resizable=no,status=no,location=no,toolbar=no,menubar=no,fullscreen=no,scrollbars=no,dependent=no'); return false;">Grade 8.8 bolts</a>
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":sunshine: :x-connect: Boost Days: What's on this week :x-connect: :sunshine:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Good morning Brisbane and hope you all had a fab weekend! :sunshine: \n\n Please see below for what's on this week! :yay: Due to the low attendance last week in the office, we have changes to the boost program this week. "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-12: Monday, 12th January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee: *Café Partnership*: Enjoy free coffee and café-style beverages from our Cafe partner *Industry Beans*.\n\n :croissant: Morning tea from 9am in the kitchen. \n:Lunch: Delicious *Greenstreat salads* provided in the kitchen from *12pm* in the kitchen."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-14: Wednesday, 14th January",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Café Partnership*: Enjoy free coffee and café-style beverages from our Cafe partner *Industry Beans*. \n\n:lunch: *Morning Tea*:from *9am* in the kitchen!"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-16:Friday, 16th January ",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":cheers-9743: :cheese: *Happy Hour & Happy Friday:* from 3pm - 4pm in the kitchen! Wind down for the week over some drinks and nibbles."
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0?cid=Y19uY2M4cDN1NDRsdTdhczE0MDhvYjZhNnRjb0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Brisbane Social Calendar*>, and get ready to Boost your workdays!\n\nLove,\nWX Team :party-wx:"
			}
		}
	]
}
star

Thu Jan 29 2026 04:38:11 GMT+0000 (Coordinated Universal Time)

@staceylai

star

Tue Jan 27 2026 01:36:45 GMT+0000 (Coordinated Universal Time)

@davidmchale

star

Mon Jan 26 2026 10:13:43 GMT+0000 (Coordinated Universal Time) https://www.uniccm.com/blog/the-history-of-the-atomic-structure

@mateoardanza

star

Fri Jan 23 2026 11:48:36 GMT+0000 (Coordinated Universal Time)

@usman13

star

Fri Jan 23 2026 07:50:07 GMT+0000 (Coordinated Universal Time) https://www.yumeustechnologies.com/nowpayments-clone-script

@JohnFrancis #nowpaymentsclonescript #nowpaymentsclone #nowpayments

star

Fri Jan 23 2026 05:14:21 GMT+0000 (Coordinated Universal Time)

@@ankita123

star

Fri Jan 23 2026 05:06:59 GMT+0000 (Coordinated Universal Time)

@@ankita123

star

Thu Jan 22 2026 23:32:55 GMT+0000 (Coordinated Universal Time)

@nofil

star

Thu Jan 22 2026 21:34:59 GMT+0000 (Coordinated Universal Time) https://wedevs.com/blog/105501/disable-woocommerce-variable-product-price/

@EssquePro

star

Thu Jan 22 2026 15:50:27 GMT+0000 (Coordinated Universal Time) https://mergecsv.org

@SoulDee #typescript

star

Thu Jan 22 2026 10:28:49 GMT+0000 (Coordinated Universal Time)

@tanuja123

star

Thu Jan 22 2026 07:52:09 GMT+0000 (Coordinated Universal Time) https://www.reddit.com/r/youtubedl/comments/lbrb2y/downloading_embedded_vimeo_videos/

@teressider

star

Thu Jan 22 2026 07:01:29 GMT+0000 (Coordinated Universal Time)

@Saravana_Kumar #python

star

Thu Jan 22 2026 02:46:30 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Wed Jan 21 2026 14:40:04 GMT+0000 (Coordinated Universal Time)

@jrg_300i #javascript

star

Wed Jan 21 2026 07:27:14 GMT+0000 (Coordinated Universal Time) https://www.dappsfirm.com/pragmatic-play-clone-script

@TimDavid16 #pragmaticplayclonescript

star

Wed Jan 21 2026 03:22:42 GMT+0000 (Coordinated Universal Time)

@davidmchale #dataset #prevent #duplicate #event #listener

star

Wed Jan 21 2026 00:06:47 GMT+0000 (Coordinated Universal Time) https://curc.readthedocs.io/en/latest/programming/OpenMP-C.html

@luisjdominguezp

star

Wed Jan 21 2026 00:02:40 GMT+0000 (Coordinated Universal Time) https://curc.readthedocs.io/en/latest/programming/OpenMP-C.html

@luisjdominguezp

star

Tue Jan 20 2026 07:17:14 GMT+0000 (Coordinated Universal Time)

@usman13

star

Tue Jan 20 2026 03:36:44 GMT+0000 (Coordinated Universal Time)

@davidmchale #toggle #aria-label

star

Mon Jan 19 2026 12:14:31 GMT+0000 (Coordinated Universal Time) https://www.blockintelligence.io/Blockchain-Development

@Zarafernandes #trustedtechnology #blockchainbusiness #blockchainexperts #blockchain #blockchaininnovation

star

Mon Jan 19 2026 11:38:07 GMT+0000 (Coordinated Universal Time) https://www.thecryptoape.com/poloniex-clone-script

@Davidbrevis

star

Mon Jan 19 2026 07:24:06 GMT+0000 (Coordinated Universal Time) https://indextts-2.online/

@SoulDee

star

Mon Jan 19 2026 07:22:22 GMT+0000 (Coordinated Universal Time) https://parquettocsv.online

@SoulDee

star

Mon Jan 19 2026 02:20:47 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Sun Jan 18 2026 22:55:00 GMT+0000 (Coordinated Universal Time)

@nurud43

star

Sun Jan 18 2026 22:52:56 GMT+0000 (Coordinated Universal Time)

@nurud43

star

Sun Jan 18 2026 22:48:58 GMT+0000 (Coordinated Universal Time)

@nurud43

star

Fri Jan 16 2026 19:38:22 GMT+0000 (Coordinated Universal Time)

@1234_5

star

Fri Jan 16 2026 08:19:25 GMT+0000 (Coordinated Universal Time) https://www.nativeassignmenthelp.co.uk/

@jamesstone

star

Fri Jan 16 2026 07:48:22 GMT+0000 (Coordinated Universal Time)

@2late #excel

star

Thu Jan 15 2026 03:59:56 GMT+0000 (Coordinated Universal Time)

@davidmchale #closest

star

Thu Jan 15 2026 03:58:28 GMT+0000 (Coordinated Universal Time)

@davidmchale #preventdefault #testing

star

Thu Jan 15 2026 03:56:34 GMT+0000 (Coordinated Universal Time)

@davidmchale #preventdefault #testing

star

Wed Jan 14 2026 16:15:27 GMT+0000 (Coordinated Universal Time)

@jrg_300i #javascript

star

Wed Jan 14 2026 13:54:25 GMT+0000 (Coordinated Universal Time) https://chat.mistral.ai/chat

@teressider

star

Wed Jan 14 2026 06:36:01 GMT+0000 (Coordinated Universal Time) https://www.coinsclone.com/top-centralized-exchange-clone-scripts/

@Emmawoods

star

Wed Jan 14 2026 06:13:23 GMT+0000 (Coordinated Universal Time) https://medium.com/cryptocurrency-scripts/how-does-opensea-make-money-f443b0bc8794

@LilianAnderson #opensearevenue #nftmarketplacegrowth #howopenseamakesmoney #nftbusinessmodel #openseamarketvalue

star

Wed Jan 14 2026 03:40:17 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Tue Jan 13 2026 23:36:38 GMT+0000 (Coordinated Universal Time)

@davidmchale #sessionstorage

star

Tue Jan 13 2026 13:26:20 GMT+0000 (Coordinated Universal Time)

@divyasoni23 #javascript #jquery

star

Mon Jan 12 2026 05:59:18 GMT+0000 (Coordinated Universal Time) https://www.softean.com/cryptocurrency-exchange-development

@Amybonbo

star

Sun Jan 11 2026 15:13:56 GMT+0000 (Coordinated Universal Time) https://stringart.online/

@SoulDee

star

Sun Jan 11 2026 15:13:03 GMT+0000 (Coordinated Universal Time) https://stringart.online/random-string/

@SoulDee #typescript

star

Sun Jan 11 2026 15:08:37 GMT+0000 (Coordinated Universal Time) https://px2rem.com/

@SoulDee

star

Sun Jan 11 2026 15:03:15 GMT+0000 (Coordinated Universal Time) https://px2rem.com/

@SoulDee #typescript

star

Thu Jan 08 2026 13:08:51 GMT+0000 (Coordinated Universal Time) https://screw.full-design.com/grade-8-8-bolt-the-steel-elixir-in-the-fastening-industry-81814969

@hamilton222

star

Thu Jan 08 2026 00:27:13 GMT+0000 (Coordinated Universal Time)

@FOHWellington

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension