<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Tech Blog Jolimoi]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://tech.jolimoi.com/</link><image><url>https://tech.jolimoi.com/favicon.png</url><title>Tech Blog Jolimoi</title><link>https://tech.jolimoi.com/</link></image><generator>Ghost 5.69</generator><lastBuildDate>Wed, 13 May 2026 10:51:31 GMT</lastBuildDate><atom:link href="https://tech.jolimoi.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[The Hidden Traps of Scaling Data Operations—and How to Beat Them]]></title><description><![CDATA[<p>Scaling data operations isn&#x2019;t easy, but most obstacles are predictable and avoidable. After speaking with current or ex-Head of Data/CTO/CEO or CPO from companies like <a href="https://www.labellevie.com/?ref=tech.jolimoi.com" rel="noopener">La Belle Vie</a>, <a href="https://pro.bsport.io/?ref=tech.jolimoi.com" rel="noopener">BSport</a>, <a href="https://www.qare.fr/?ref=tech.jolimoi.com" rel="noopener">Qare</a>, <a href="https://sundayapp.com/fr/?ref=tech.jolimoi.com" rel="noopener">Sunday</a> or <a href="https://www.leboncoin.fr/?ref=tech.jolimoi.com" rel="noopener">LeBonCoin</a>, one thing is clear: the biggest challenges are often self-inflicted. From messy governance</p>]]></description><link>https://tech.jolimoi.com/scaling-data-operations-insights-from-interviews-with-heads-of-data-ctos-and-cpos/</link><guid isPermaLink="false">67068799311db70001089d62</guid><category><![CDATA[data-governance]]></category><category><![CDATA[startup]]></category><dc:creator><![CDATA[Alexis Blandin]]></dc:creator><pubDate>Tue, 28 Jan 2025 17:54:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1590278458425-6aa3912a48a5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG1hemV8ZW58MHx8fHwxNzM4MDgwMDI0fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1590278458425-6aa3912a48a5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG1hemV8ZW58MHx8fHwxNzM4MDgwMDI0fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="The Hidden Traps of Scaling Data Operations&#x2014;and How to Beat Them"><p>Scaling data operations isn&#x2019;t easy, but most obstacles are predictable and avoidable. After speaking with current or ex-Head of Data/CTO/CEO or CPO from companies like <a href="https://www.labellevie.com/?ref=tech.jolimoi.com" rel="noopener">La Belle Vie</a>, <a href="https://pro.bsport.io/?ref=tech.jolimoi.com" rel="noopener">BSport</a>, <a href="https://www.qare.fr/?ref=tech.jolimoi.com" rel="noopener">Qare</a>, <a href="https://sundayapp.com/fr/?ref=tech.jolimoi.com" rel="noopener">Sunday</a> or <a href="https://www.leboncoin.fr/?ref=tech.jolimoi.com" rel="noopener">LeBonCoin</a>, one thing is clear: the biggest challenges are often self-inflicted. From messy governance to tech stacks that don&#x2019;t scale, let&#x2019;s skip the fluff and dive straight into what works (and what doesn&#x2019;t).</p><h3 id="1-centralize-now-specialize-later">1. Centralize now, specialize later</h3><p>Don&#x2019;t overthink it. Early on, you need a small, centralized team that can enforce governance and standardize processes. Skip the urge to hire specialists. Get the basics right first&#x200A;&#x2014;&#x200A;clean pipelines, solid reporting and clear ownership. When the time comes to expand, specialize your team around key business needs.</p><p><strong>&#x26A0;&#xFE0F; Trap to avoid:</strong> Creating silos too early by scattering specialists across teams</p><p><strong>&#x1F4A1;</strong> <strong>Actionable tip:</strong> Start with generalists using flexible tools like dbt or Looker. Specialize only when your operational load demands it</p><h3 id="2-pick-a-tech-stack-that-scales">2. Pick a tech stack that&#xA0;scales</h3><p>Your tools should never hold you back. If you&#x2019;re still using outdated solutions, you&#x2019;re already behind. The modern data stack is cloud-based, modular, and designed for growth. Think Snowflake, BigQuery, or Databricks. Stop patching systems together and invest in tech that&#x2019;ll save you headaches down the road.</p><p><strong>&#x26A0;&#xFE0F;Trap to avoid:</strong> Locking yourself into rigid, legacy systems</p><p><strong>&#x1F4A1;Actionable tip:</strong> Map out where your business will be in three years. Choose tools that can handle 10x the data volume you&#x2019;re working with today</p><h3 id="3-governance-is-non-negotiable">3. Governance is non-negotiable</h3><p>It&#x2019;s tempting to leave governance for &#x201C;later.&#x201D; Don&#x2019;t, please. By the time you realize you need it, it&#x2019;ll be too late. Strong governance ensures trust, security, and compliance. Start small: standardized data definitions, access controls, and audit trails. Build from there.</p><p><strong>&#x26A0;&#xFE0F;Trap to avoid:</strong> Scrambling to retrofit governance when regulations hit</p><p><strong>&#x1F4A1;Actionable tip:</strong> Implement automated tools like Monte Carlo or CastorDoc to monitor data quality and compliance from day one</p><h3 id="4-data-must-serve-business-goals">4. Data must serve business&#xA0;goals</h3><p>If your data isn&#x2019;t driving decisions, what&#x2019;s the point? Forget dashboards no one reads or non-actionable so-called KPIs with no impact. Your data should be laser-focused on solving business-critical problems. Tie every data initiative to clear, measurable outcomes.</p><p><strong>&#x26A0;&#xFE0F;Trap to avoid:</strong> Becoming a request factory for ad-hoc requests</p><p><strong>&#x1F4A1;Actionable tip:</strong> Say no to low-value. Instead, build scalable solutions that answer recurring questions</p><h3 id="5-balance-your-team">5. Balance your&#xA0;team</h3><p>Too many juniors, and progress slows to a crawl. Too many seniors, and your budget implodes. The key is balance. Juniors need mentorship; seniors need to stay focused on high-impact tasks. Keep your team lean but effective.</p><p><strong>Trap to avoid:</strong> Thinking more headcount means more output</p><p><strong>&#x1F4A1;Actionable tip:</strong> Pair every junior hire with a senior mentor to fast-track learning and autonomy</p><h3 id="no-excuses-scale-smart">No excuses. Scale&#xA0;smart</h3><p>Scaling isn&#x2019;t about luck; it&#x2019;s about preparation. The biggest mistakes happen when teams try to rush without a solid foundation. Centralize first, invest in scalable tech, enforce governance, and focus on business impact. If you&#x2019;re not doing this, your data operations aren&#x2019;t ready to scale.&#xA0;</p><h3 id></h3>]]></content:encoded></item><item><title><![CDATA[Multi-label Classification Problems with Large Langage Models]]></title><description><![CDATA[<p>In today&apos;s data-driven world, accurately categorizing information has become crucial. The task of multi-label classification, where data can belong to multiple categories simultaneously, addresses this need effectively. Unlike traditional single-label classification, multi-label classification mirrors the complexity of real-world data and often comes to the forefront in wider data</p>]]></description><link>https://tech.jolimoi.com/multi-label-classification-problems-with-large-langage-models/</link><guid isPermaLink="false">66a0d20342fad100010c43e5</guid><category><![CDATA[llm]]></category><category><![CDATA[classification]]></category><category><![CDATA[data science]]></category><dc:creator><![CDATA[Martin Labenne]]></dc:creator><pubDate>Tue, 06 Aug 2024 15:20:04 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1554900773-4dd76725f876?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDZ8fGFyY2hpdmUlMjBvcmRlcnxlbnwwfHx8fDE3MjE4MjMyMjl8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1554900773-4dd76725f876?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDZ8fGFyY2hpdmUlMjBvcmRlcnxlbnwwfHx8fDE3MjE4MjMyMjl8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Multi-label Classification Problems with Large Langage Models"><p>In today&apos;s data-driven world, accurately categorizing information has become crucial. The task of multi-label classification, where data can belong to multiple categories simultaneously, addresses this need effectively. Unlike traditional single-label classification, multi-label classification mirrors the complexity of real-world data and often comes to the forefront in wider data analysis efforts. This problem is particularly critical in areas such as social media tagging, news organization, disease diagnosis, and product recommendation. It becomes especially challenging in text analysis, where a single span of text can reference multiple notions in nuanced ways.</p><p>While traditional <a href="https://en.wikipedia.org/wiki/Natural_language_processing?ref=tech.jolimoi.com">Natural Language Processing</a> (NLP) techniques have been highly effective for many tasks, they often require substantial domain knowledge and manual feature engineering. Advances in deep learning and the emergence of <a href="https://en.wikipedia.org/wiki/Large_language_model?ref=tech.jolimoi.com">Large Language Models</a> (LLMs) have shifted the landscape, offering more powerful and automated solutions for complex NLP problems, as well as a more precise and insightful approach to text analysis.</p><h1 id="tldr"><strong>TL;DR</strong></h1><p>Multi-label classification, crucial for tasks like social media tagging, is greatly enhanced by LLMs. These models automate the handling of complex, real-world data, making them ideal when traditional model training is too complex. With user-friendly APIs, LLMs offer cost-effective, high-performance solutions for text analysis. Techniques like few-shot prompting and chain of thought further improve their accuracy. Regular monitoring and evaluation ensure these models stay effective in production.</p><h1 id="a-quick-note-on-multi-label-classification">A quick note on Multi Label Classification</h1><p>In multi-label classification, unlike multi-class classification where each instance is assigned to exactly one out of many classes, each instance can be assigned to zero, one, or more classes. This means that each class label is not mutually exclusive, and the number of labels per instance isn&apos;t fixed. Indeed, each instance in the dataset can have one or more labels assigned to it, or potentially none at all. As such, there can be relationships or dependencies among the labels, meaning the presence of one label might influence the presence of another.</p><p>These labels can be represented in various ways:</p><ul><li>One column per category containing <strong>binary indicators</strong> (0 or 1) showing whether the label is applicable to the document ;</li><li>A <strong>list of labels</strong> associated with the text content, stored in a single column.</li></ul><table>
<thead>
<tr>
<th>ID</th>
<th>Content</th>
<th>Labels</th>
<th>Politics</th>
<th>Economy</th>
<th>Sports</th>
<th>Entertainment</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>&quot;Government passes new healthcare reform.&quot;</td>
<td>[&quot;Politics&quot;]</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>&quot;Stock market hits new highs amid economic boom.&quot;</td>
<td>[&quot;Economy&quot;]</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>&quot;Celebrity singer releases new music video.&quot;</td>
<td>[&quot;Entertainment&quot;]</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>4</td>
<td>&quot;Local sports team wins championship game.&quot;</td>
<td>[&quot;Sports&quot;]</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>5</td>
<td>&quot;Election debate highlights key economic policies.&quot;</td>
<td>[&quot;Politics&quot;, &quot;Economy&quot;]</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>6</td>
<td>&quot;AI will take on the world&#x201D;</td>
<td>[ ]</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table><p>This type of problem is particularly challenging because as the number of possible labels increases, the label matrix becomes more sparse. This means there may be very few examples for many label combinations, making it difficult for models to learn effectively. Typically, a large amount of data is required for model training in such cases.</p><p>But what should you do when you don&#x2019;t have the data to tackle multi labels classification problems in a text setting or you don&apos;t have the resources to build it ?</p><h1 id="why-should-you-choose-llms-over-traditional-nlp-techniques-for-text-analysis">Why Should You Choose LLMs Over Traditional NLP Techniques for Text Analysis?</h1><p>Traditionally, NLP project involve multiple phases, such as:</p><ul><li><strong>Preprocessing</strong>: converting all text to lowercase, removing punctuation, special characters and numbers, reducing words to their base form through stemming or lemmatization</li><li><strong>Feature Extraction</strong>: using Bag of Words or N-grams techniques</li><li><strong>Model Selection</strong> and <strong>Hyper Parameter tuning</strong></li></ul><p>The specific case of multi label classification always comes with a set of challenges, the two main ones being:</p><ul><li><strong>Label Imbalance</strong>: Some labels might appear very frequently in the dataset, while others are rare. Usually the more imbalanced is the data, the more difficult will be the model training.</li><li><strong>Correlation Among Labels</strong>: The inter-dependency between labels can complicate the modeling process, as the predictive model must effectively learn these dependencies.</li></ul><p>From pre-processing to model validation, this process can take a lot of time and resources.</p><p>Luckily, we live in a world where pre-trained specialized language models are readily available. Additionally, providers offer access to large generalist models trained on massive amounts of text, known as Large Language Models (LLMs). Large Language Models are ideal for text analysis due to their ability to understand and generate human-like text. They can efficiently handle a wide range of tasks such as summarization, sentiment analysis and language translation in most languages. Their training on vast datasets allows them to recognize patterns and nuances in text, making them versatile and powerful tools for extracting insights and automating language-related tasks.</p><p>Why should you choose an LLM for text analysis ?</p><ul><li><strong>Easy to use</strong>: LLMs are ready to use and do not require in-depth coding skills or extensive knowledge of data science and machine learning. Providers offer user-friendly APIs, making it simple to integrate LLMs into your applications, regardless of the programming language you use. Despite being a relatively recent technology in the mainstream, comprehensive documentation, tutorials, and community support are available to help users get started quickly. In most cases, the text does not even have to be preprocessed.</li><li><strong>Cost Considerations:</strong> Deploying a language model can be cost-intensive, especially if you don&apos;t already have access to a GPU. Nowadays, the best models for any language-related task have a neural network architecture. Using GPUs for running language models in production ensures efficient operation, delivering high performance and quick responses. However, setting up a GPU-equipped instance, whether in the cloud or on-premises, can significantly increase deployment and exploitation costs. For performing tasks on small text spans, considering the use of LLM providers&apos; inference services can be more cost-effective because they charge per token (a sub-portion of a word).</li><li><strong>Performance:</strong> LLMs perform very well in most cases. Interestingly, the output of the model can be adjusted easily by providing it with one or more examples which will increase the quality of predictions.</li></ul><p>It&apos;s often mentioned that LLMs are not deterministic, meaning the same query can produce different responses. While this is true, for simple tasks like classification, it is very unlikely to get different answers. Additionally, providers like OpenAI offer a <code>seed</code> parameter to achieve mostly deterministic results by imposing the random factor value.</p><p>Choosing to use an LLM over traditional NLP techniques can significantly speed up the development process for any text analysis task.</p><p>However, you will still need a test dataset to evaluate how well your solution performs in your specific use case. For multi-label classification tasks, a good testing dataset should reflect the complexity of your use case. Each sample should follow a consistent format, and the dataset should have a balanced distribution of label combinations, including samples with no label. If you know the real-world distribution of the labels, aim to match your test dataset to it. Generally, your test dataset should contain at least a few hundred samples, but the more labels you have, the larger your dataset needs to be. Ideally, the more the better.</p><p>Regularly generating test cases with fresh data should be a standard practice, as this enables you to monitor the model&apos;s performance in real-world conditions using real-life data.</p><h1 id="production-challenges">Production challenges</h1><h2 id="quality-of-predictions-and-monitoring"><strong>Quality of Predictions and Monitoring</strong></h2><p>Classification is a crucial aspect of data analysis and strategic decision-making, demanding high-quality predictions to be effective. To evaluate the quality of predictions, there are numerous metrics available, each focusing on different aspects of performance (see annexe on classification metrics). For example, a metric such as Precision Score helps determine how well the classifier performs at prioritizing true positives over false negatives.</p><p>In production environments, tracking the outcome of each model call is vital. Storing the input and output traces enables post-analysis, helping identify accurate and inaccurate predictions. This trace analysis helps in developing strategies to enhance prediction quality and provides insights into token usage and call duration. To visualize the stored traces, you could use tools like <a href="https://www.langchain.com/langsmith?ref=tech.jolimoi.com">LangSmith</a> or <a href="https://phoenix.arize.com/?ref=tech.jolimoi.com">Phoenix</a> which provide tools to monitor LLM applications. Note that longer token sequences can lead to increased generation time, which should be considered when optimizing performance. Continuous evaluation of the model&apos;s performance with fresh data is also essential. Regular assessments ensure that the model remains relevant and accurate over time. This can be done through manual reviews or by employing another LLM to evaluate the classifier&apos;s output, a strategy known as <a href="https://huggingface.co/learn/cookbook/llm_judge?ref=tech.jolimoi.com">LLM as a judge</a>. This method helps in maintaining the model&apos;s efficacy by integrating real-world feedback.</p><p>Additionally, refining the model involves experimenting with different prompts to eventually improve results. When testing various prompts, it&apos;s important to store each prompt template along with its corresponding classification report. This allows for a thorough comparison based on chosen metrics to determine which prompt yields the best results.</p><p>An example of multi-label classification Report</p><pre><code class="language-python">import numpy as np
import pandas as pd

from sklearn.metrics import accuracy_score, classification_report, hamming_loss, zero_one_loss, jaccard_score, precision_recall_fscore_support, multilabel_confusion_matrix
from sklearn.preprocessing import MultiLabelBinarizer

def get_scores(labels_true: pd.Series, labels_pred: pd.Series, labels: list[str] = [], verbose=False) -&gt; dict[float | dict[float]]: 
    mlb = MultiLabelBinarizer()
    if len(labels) == 0: 
        labels_true_binary = mlb.fit_transform(labels_true)
    else: 
        _ = mlb.fit([labels])
        labels_true_binary = mlb.transform(labels_true)

    labels_pred_binary = mlb.transform(labels_pred)

    subset_accuracy_score = accuracy_score(labels_true_binary, labels_pred_binary)
    ham_loss = hamming_loss(labels_true_binary, labels_pred_binary)
    multilabel_zero_one_loss = zero_one_loss(labels_true_binary, labels_pred_binary)

    report = classification_report(
        labels_true_binary, labels_pred_binary, 
        zero_division=np.nan, 
        output_dict=True, 
        target_names=mlb.classes_
    )

    jaccard_micro = jaccard_score(labels_true_binary, labels_pred_binary, average=&apos;micro&apos;, zero_division=&quot;warn&quot;)
    jaccard_macro = jaccard_score(labels_true_binary, labels_pred_binary, average=&apos;macro&apos;, zero_division=&quot;warn&quot;)
    jaccard_weighted = jaccard_score(labels_true_binary, labels_pred_binary, average=&apos;weighted&apos;, zero_division=&quot;warn&quot;)
    jaccard_samples = jaccard_score(labels_true_binary, labels_pred_binary, average=&apos;samples&apos;, zero_division=&quot;warn&quot;)

    label_wise_jaccard = jaccard_score(labels_true_binary, labels_pred_binary, average=None, zero_division=&quot;warn&quot;)

    report[&apos;weighted avg&apos;].update({&apos;jaccard score&apos;: jaccard_weighted})
    report[&apos;micro avg&apos;].update({&apos;jaccard score&apos;: jaccard_micro})
    report[&apos;macro avg&apos;].update({&apos;jaccard score&apos;: jaccard_macro})
    report[&apos;samples avg&apos;].update({&apos;jaccard score&apos;: jaccard_samples})

    for i, label in enumerate(mlb.classes_):
        report[label].update({&apos;jaccard score&apos;: label_wise_jaccard[i]})

    if verbose: 
        print(f&quot;&quot;&quot;
Accuracy Score: { subset_accuracy_score }
Zero One Loss: { multilabel_zero_one_loss }
Hamming Loss: { ham_loss }
# =================================================================== #
{ pd.DataFrame(report).T }
# =================================================================== #
        &quot;&quot;&quot;)

    return {
        &apos;accuracy_score&apos;: subset_accuracy_score, 
        &apos;zero_one_loss&apos;: multilabel_zero_one_loss,
        &apos;hamming_loss&apos;: ham_loss,
        &apos;report&apos;: report
     }
</code></pre><p><code>MultiLabelBinarizer()</code> is used to convert the multi-label data into a binary format suitable for evaluation metrics.</p><p>Several metrics are used to evaluate the model&apos;s performance, see definition in annexe. <code>classification_report</code> computes precision, recall, f1-score and support at the same time, for each label and in average.</p><p>If this function is called in <code>verbose</code> mode, it displays a comprehensive multi label classification report. It always return the report structured as a dictionary.</p><p>By systematically evaluating performance, experimenting with prompts, and analyzing outcomes, you can continuously improve the classification process and ensure its effectiveness in real-world applications.</p><h2 id="price-time-quality-trade-off">Price, Time, Quality trade-off</h2><p>Since LLMs entered the mainstream, various techniques have been developed to address specific problems and improve prediction quality. Notable methods include <a href="https://www.promptingguide.ai/techniques/fewshot?ref=tech.jolimoi.com">few-shot prompting</a>, <a href="https://www.promptingguide.ai/techniques/cot?ref=tech.jolimoi.com">chain of thought</a>, and <a href="https://www.promptingguide.ai/techniques/tot?ref=tech.jolimoi.com">tree of thoughts</a>, with new techniques emerging frequently. Each method uses different numbers of tokens in the input and output, impacting performance, speed, and applicability. Providers typically allocate 1/4 of costs to input tokens and 3/4 to output tokens. Understanding token distribution is crucial for managing costs and latency: it is essential to select the appropriate technique based on your budget and requirements, considering that more tokens lead to higher costs and longer execution times.</p><p>Techniques like chain of thought and tree of thoughts encourage the LLM to &quot;think&quot; more deeply. While these methods excel in performance for simple and complex problems, they are also more costly and time-consuming due to increased token usage. Chain of thought involves the LLM generating a step-by-step explanation of the final result. Tree of thoughts involves multiple &quot;specialists&quot; debating and presenting arguments to reach a final answer. Both techniques generate a substantial number of output tokens, leading to higher costs.</p><p><em>Example of Chain of Thoughts</em></p><blockquote>I went to the market and bought 10 apples. I gave 2 apples to the neighbor and 2 to the repairman. I then went and bought 5 more apples and ate 1. How many apples did I remain with?<br>Let&apos;s think step by step.</blockquote><p><em>Example of Tree of Thoughts</em></p><blockquote>Imagine three different experts are answering this question.<br>All experts will write down 1 step of their thinking,<br>then share it with the group.<br>Then all experts will go on to the next step, etc.<br>If any expert realizes they&apos;re wrong at any point then they leave.<br>The question is: If I bought 10 apples, gave 2 to the neighbor and 2 to the repairman, then bought 5 more apples and ate 1, how many apples do I have left?</blockquote><p>Few-shot prompting leverages the model&apos;s ability to generalize from limited examples (shots) and perform tasks with minimal explicit instruction. This technique is particularly useful in scenarios where acquiring large labeled datasets is impractical. It is versatile, adapting to a wide range of tasks and is easy to implement: you simply provide a brief explanation of the task along with a small set of input-output pairs as examples. One of the most challenging part is selecting appropriate examples because they are crucial for the model to accurately infer the task&apos;s structure and desired output format.</p><p><em>Exemple of Few-Shot Prompting (here it is a 1-shot example)</em></p><p>You are a 3rd grade student tasked with answering math problems in 1 line.<br>User: Lily has 12 apples. She wants to give an equal number of apples to her 3 friends. How many apples will each friend get<br>Assistant: 12 &#xF7; 3 = 4<br>User: If I bought 10 apples, gave 2 to the neighbor and 2 to the repairman, then bought 5 more apples and ate 1, how many apples do I have left?</p><p>For multi-label classification tasks, the minimal required output is a list of predicted labels. Few-shot prompting may involve a larger input token volume when incorporating numerous examples, but ultimately results in fewer tokens in the output by ensuring a concise and easily exploitable format. By focusing on a controlled output format, this approach offers an economical solution, as four words in the input cost the same as one word in the output.</p><p>For scenarios where budget and latency are not a problem Chain of Thoughts or Tree of Thoughts coupled with a well structured prompt and answer can also be a viable alternative.</p><h2 id="rate-limiting-for-api-calls">Rate Limiting for API Calls</h2><p>In scenarios where APIs impose limits on the number of requests that can be made within a specific timeframe, implementing a rate limiter becomes crucial. This ensures that applications stay within acceptable usage boundaries and prevent overwhelming the API provider with excessive requests. The <code>ratelimit</code> package simplifies this process by providing decorators that seamlessly integrate rate limiting into your Python functions.</p><p>Lets break down how it works:</p><pre><code class="language-python">from openai import OpenAI
from ratelimit import limits, sleep_and_retry

RATE_LIMIT_PERIOD = 60  # 60 seconds (1 minute)
RATE_LIMIT_CALLS = 50   # 50 calls per minute

def get_client():
    client = OpenAI(api_key=API_KEY)
    return client

@sleep_and_retry
@limits(calls=RATE_LIMIT_CALLS, period=RATE_LIMIT_PERIOD)
def get_chat_completion(messages):
    client = get_client()
    chat_completion = client.chat.completions.create(
        model=MODEL_NAME,
        messages=messages,
        stream=False,
        temperature=0,
        seed=424242
    )
    return chat_completion
</code></pre><p><code>RATE_LIMIT_PERIOD</code> specifies the duration of the rate limiting window in seconds.</p><p><code>RATE_LIMIT_CALLS</code> indicates the maximum number of API calls allowed within the defined period.</p><p><code>@limits(calls=RATE_LIMIT_CALLS, period=RATE_LIMIT_PERIOD)</code> decorator enforces the rate limit on the <code>get_chat_completion</code> function.</p><p><code>@sleep_and_retry</code> decorator wraps around the rate-limited function. When the rate limit is exceeded, it handles the excess calls by delaying and retrying them once the current rate-limiting window expires.</p><p>In our example, <code>get_chat_completion</code> is a function that interacts with OpenAI&apos;s chat API (<code>client.chat.completions.create</code>). If the function is called more than 50 times within a minute, the <code>sleep_and_retry</code> decorator ensures that the excess calls are delayed until the rate-limiting period resets.</p><p>By adhering to rate limits, you can ensure that your application interacts responsibly with APIs, avoiding service interruptions and potential outages.</p><h1 id="a-multi-label-classifier-with-few-shot-prompting-and-openai-api">A Multi-label Classifier with Few-Shot Prompting and OpenAI API</h1><p>The following example presents how to make a multi-label classifier that tags short pieces of text. The classifier can select zero to many categories from &apos;<em>sports</em>&apos;, &apos;<em>politics</em>&apos;, &apos;<em>economy</em>&apos;, and &apos;<em>entertainment</em>&apos;:</p><pre><code class="language-python">def intersection(lst1, lst2):
    return list(set(lst1) &amp; set(lst2))

def get_labels_from_chat_completion(
    chat_completion, 
    labels_wanted: list[str] = None, 
    labels_prefix: str = None
) -&gt; list[str]: 
    
    if len(chat_completion.choices) == 0 :
        return []
    
    chat_completion_message_content = chat_completion.choices[0].message.content

    if labels_prefix is not None: 
        chat_completion_message_content = chat_completion_message_content.replace(labels_prefix, &quot;&quot;)

    labels_str = chat_completion_message_content.strip()
    
    if len(labels_str) == 0: 
        return []

    labels = labels_str.split(&apos;,&apos;)
    cleaned_labels = [label.strip() for label in labels]

    if labels_wanted is not None: 
        cleaned_labels = intersection(labels_wanted, cleaned_labels)

    cleaned_labels.sort()
    return cleaned_labels 

def multi_label_llm(content_txt: str): 
    if len(content_txt) == 0:
        return []

    messages = [
            {
                &quot;role&quot;: &quot;system&quot;,
                &quot;content&quot;: &quot;You are a multi-label classifier tasked with identifying appropriate tags for a given text. Return the tags as a simple list separated by commas. If no tags apply, return nothing. The available tags are: &apos;sports&apos;, &apos;politics&apos;, &apos;economy&apos;, and &apos;entertainment&apos;. Always consider the context of the text to determine the relevance of each tag.&quot;
            },
            {
                &quot;role&quot;: &quot;user&quot;,
                &quot;content&quot;: &quot;Text: &apos;Election debate highlights key economic policies.&apos;&quot;
            },
            {
                &quot;role&quot;: &quot;assistant&quot;,
                &quot;content&quot;: &quot;Tags:politics,economy&quot;
            },
            {
                &quot;role&quot;: &quot;user&quot;,
                &quot;content&quot;: &quot;Text: &apos;AI will take on the world.&apos;&quot;
            },
            {
                &quot;role&quot;: &quot;assistant&quot;,
                &quot;content&quot;: &quot;Tags:&quot;
            }
    ]
    messages.append(
        {
            &quot;role&quot;:&quot;user&quot;,
            &quot;content&quot;: &quot;Text: &apos;{content_txt}&apos;&quot;
        }
    )
    chat_completion = get_chat_completion(messages)
    labels = get_labels_from_chat_completion(chat_completion, labels_wanted=[&apos;sports&apos;, &apos;politics&apos;, &apos;economy&apos;, &apos;entertainment&apos;], labels_prefix=&apos;Tags:&apos;)
    return labels
    
multi_label_llm(
    &quot;Stock market hits new highs amid economic boom.&quot;
)
</code></pre><p><code>intersection</code> compute the intersection of two lists, i.e. the elements that are common to both lists.</p><p><code>get_labels_from_chat_completion</code> processes the chat completion response to extract and clean labels. It handles a possible response prefix, splits the labels from the text into an array, trims whitespace, filters out unwanted labels and sorts the final list of labels.</p><p><code>multi_label_llm</code> processes a text through a LLM that predicts which labels apply to the text. The context and goal of the task are explained in the <code>system</code> prompt. Two pairs of examples are added to the <code>messages</code> stack to help the model understand the format of the answer and the subtleties of the task. The text we want to process is provided as the last element of the <code>messages</code> stack, which is then sent to the LLM. Finally, the answer is formatted to return an array of strings.</p><p>Note that with Few-Shot Prompting, adding more labels to the classification task can reduce precision. The language model might struggle to accurately identify the most relevant labels when more options are available, potentially leading to less precise tagging. If this is the case and your labels allow it, a good workaround is to perform consecutive calls: first, a general one to determine broad categories, which can then trigger more specialized labeling calls. It&apos;s also worth experimenting with more complex techniques that are less affected by this issue.</p><h1 id="conclusion">Conclusion</h1><p>Leveraging Large Language Models (LLMs) for Multi-Label Classification in text analysis presents a powerful alternative to traditional Natural Language Processing (NLP) techniques. </p><p>The capabilities of LLMs to handle complex and nuanced data make them highly suitable for tasks where multiple labels are needed. With their user-friendly APIs, LLMs offer ease of use, cost-efficiency, and high performance, enabling rapid deployment and effective handling of real-world data challenges. </p><p>By incorporating advanced techniques like few-shot prompting, chain of thought, or tree of thoughts, users can further enhance the precision and applicability of these models, ensuring robust and scalable solutions for diverse text analysis needs. </p><p>Regular evaluation and prompt refinement are key to maintaining the accuracy and relevance of the model in production environments, ultimately driving better decision-making and strategic insights.</p><h1 id="annexe-multi-label-classification-metrics-overview">Annexe: Multi Label Classification Metrics Overview</h1><p><strong>Subset Accuracy score</strong></p><p>The Subset Accuracy Score, also known as the &#x201C;exact match ratio&#x201D;, is the strictest measure. It requires that each set of predicted labels for a sample corresponds exactly to the set of actual labels.</p><p>The Accuracy is computed for every sample then averaged on the whole set. The more the better. Ranging from 0 to 1.</p><p><strong>Subset Zero One Loss</strong></p><p>Zero One Loss is similar to subset accuracy, but rather than being a score, it&apos;s a loss where 0 means no error and 1 means at least one error in the prediction.</p><p>The Loss is then averaged on the whole set. The less the better. Ranging from 0 to 1.</p><p><strong>Hamming Loss</strong></p><p>Hamming Loss measures the fraction of labels that are incorrectly predicted, i.e. the fraction of times the wrong label is predicted, independently of the other labels.</p><p>The Loss is then averaged on the whole set. The less the better. Ranging from 0 to 1.</p><p><strong>Precision</strong></p><p>Precision measures the proportion of positive identifications that were actually correct. It is the score to prioritize if we want to <em>avoid false positives</em>: the precision is intuitively the ability of the classifier not to label as positive a sample that is negative.</p><p>For multi-label classification, multiple strategies for averaging are available:</p><ul><li><code>micro</code>: Calculate metric globally by counting the total true positives, false negatives and false positives.</li><li><code>macro</code>: Calculate metric for each label, and find their unweighted mean. This does not take label imbalance into account.</li><li><code>weighted</code>: Calculate metric for each label, and find their average weighted by support (the number of true instances for each label). This does handle well label imbalance</li><li><code>samples</code>: Calculate metric for each sample, and find their unweighted mean. In binary or multiclass setting: this strategy is equivalent to the accuracy score, but not in multilabel settings where the classifier allow samples to have multiple labels. This strategy is valuable if we want to understand how well the model captures the correct labels for each data point.</li></ul><p>The more the better. Precision is ranging from 0 to 1.</p><p><strong>Recall</strong></p><p>Recall measures the proportion of real positives that have been correctly identified. It is the score to prioritize if we want to avoid false negatives: the recall is intuitively the ability of the classifier to find all the positive samples.</p><p>For multi-label classification, the same multiple strategies as Precisions are available for averaging (micro, macro, weighted, samples).</p><p>The more the better. Recall is ranging from 0 to 1.</p><p><strong>F1-score</strong></p><p>F1-score is the harmonic mean of Precision and Recall. It combines both metrics. The relative contribution of precision and recall to the F1 score are equal: it is the score to prioritize if we want to avoid both false positives and false negatives.</p><p>For multi-label classification, the same multiple strategies as Precisions are available for averaging (micro, macro, weighted, samples).</p><p>The more the better. F1-Score is ranging from 0 to 1.</p><p><strong>Jaccard Score</strong></p><p>The Jaccard Score (or Index) measures the similarity between two sets of labels, defined as the size of the intersection divided by the size of the union of the sets of labels.</p><p></p><figure class="kg-card kg-image-card"><img src="https://media.geeksforgeeks.org/wp-content/uploads/20230811131746/How-to-Calculate-Jaccard-Similarity-in-Python.png" class="kg-image" alt="Multi-label Classification Problems with Large Langage Models" loading="lazy"></figure><p>For multi-label classification, the same multiple strategies as Precisions are available for averaging (micro, macro, weighted, samples).</p><p>The more the better. Jaccard Score is ranging from 0 to 1.</p><h1 id="sources">Sources</h1><p><a href="https://en.wikipedia.org/wiki/Multi-label_classification?ref=tech.jolimoi.com">https://en.wikipedia.org/wiki/Multi-label_classification</a></p><p><a href="https://scikit-learn.org/stable/modules/model_evaluation.html?ref=tech.jolimoi.com#classification-metrics">https://scikit-learn.org/stable/modules/model_evaluation.html#multilabel-ranking-metrics</a></p><p><a href="https://en.wikipedia.org/wiki/Jaccard_index?ref=tech.jolimoi.com">https://en.wikipedia.org/wiki/Jaccard_index</a></p><p><a href="https://scikit-learn.org/stable/modules/multiclass.html?ref=tech.jolimoi.com#multilabel-classification">https://scikit-learn.org/stable/modules/multiclass.html#multilabel-classification</a></p><p><a href="https://scikit-learn.org/stable/modules/model_evaluation.html?ref=tech.jolimoi.com#classification-metrics">https://scikit-learn.org/stable/modules/model_evaluation.html#classification-metrics</a></p><p><a href="https://platform.openai.com/docs/guides/text-generation/chat-completions-api?ref=tech.jolimoi.com">https://platform.openai.com/docs/guides/text-generation/chat-completions-api</a></p><p><a href="https://platform.openai.com/docs/guides/text-generation/reproducible-outputs?ref=tech.jolimoi.com">https://platform.openai.com/docs/guides/text-generation/reproducible-outputs</a></p><p><a href="https://platform.openai.com/docs/api-reference/chat/create?ref=tech.jolimoi.com#chat-create-seed">https://platform.openai.com/docs/api-reference/chat/create#chat-create-seed</a></p><p><a href="https://www.promptingguide.ai/techniques?ref=tech.jolimoi.com">https://www.promptingguide.ai/techniques</a></p>]]></content:encoded></item><item><title><![CDATA[Databricks Cost management]]></title><description><![CDATA[<p>&#x26A0;&#xFE0F; <em>This article was published alongside a talk we gave at a Databricks meetup, where we were invited to share insights on how we manage our costs effectively</em> </p><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vSVLr-33yXXZmjwdB1fAcWVeZ1t-gWhIxZEQgSTNiMKse559xxvbz5dlEv9MpGQuYdAkhWfn0654MMP/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe><p>While the title of this blog post is self-explanatory, I will clarify that we will not be discussing code optimization.</p><p>Costs</p>]]></description><link>https://tech.jolimoi.com/databricks-costs-management-part-1/</link><guid isPermaLink="false">666c012d42fad100010c4314</guid><category><![CDATA[databricks]]></category><category><![CDATA[cost management]]></category><category><![CDATA[finops]]></category><dc:creator><![CDATA[Alexis Blandin]]></dc:creator><pubDate>Mon, 17 Jun 2024 18:26:00 GMT</pubDate><content:encoded><![CDATA[<p>&#x26A0;&#xFE0F; <em>This article was published alongside a talk we gave at a Databricks meetup, where we were invited to share insights on how we manage our costs effectively</em> </p><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vSVLr-33yXXZmjwdB1fAcWVeZ1t-gWhIxZEQgSTNiMKse559xxvbz5dlEv9MpGQuYdAkhWfn0654MMP/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe><p>While the title of this blog post is self-explanatory, I will clarify that we will not be discussing code optimization.</p><p>Costs can certainly be linked to performance (such as model implementation and storage optimization), this subject is broad enough to warrant separate articles. </p><p>But this article will cover most of the best practices regarding handling and managing Databricks costs. One topic after the other.</p><h2 id="a-little-bit-of-context">A little bit of context</h2><p>Every company has unique insights into their spending, particularly on cloud platforms, and Databricks is no exception.</p><p>But I prefer to be, once again, clear about how we used Databricks at Jolimoi :</p><ul><li>We have a limited budget and this includes R&amp;D projects &#x1F440;</li><li>As a startup, we cannot afford to waste resources without justification. Our budget is based on a fixed % but always adjusted every month regarding the past turnover, which means no cushion at all</li><li>We mainly used Databricks for ETL and warehousing purpose</li><li><code>pip install dbt-databricks</code> &#x1F607;</li><li>We are an AWS shop</li><li>We&#x2019;re not managing petas</li></ul><h2 id="understanding-of-the-cost-structure">Understanding of the cost structure</h2><p>It seems obvious, but let&apos;s begin by understanding the components of our expenses. And for that we can refer to some good references including :</p><ul><li><a href="https://www.databricks.com/product/pricing?ref=tech.jolimoi.com" rel="noreferrer">Public Prices</a></li><li><a href="https://www.databricks.com/product/pricing/product-pricing/instance-types?ref=tech.jolimoi.com" rel="noreferrer">Pricing Calculator</a></li><li><a href="https://docs.databricks.com/en/lakehouse-architecture/cost-optimization/best-practices.html?ref=tech.jolimoi.com" rel="noreferrer">Databricks Documentation on Cost Optimization</a></li><li><a href="https://www.databricks.com/blog/best-practices-cost-management-databricks?ref=tech.jolimoi.com" rel="noreferrer">Best Practices for Cost Management</a></li><li><a href="https://docs.databricks.com/en/admin/account-settings/usage.html?ref=tech.jolimoi.com" rel="noreferrer">Account Settings and Usage</a></li></ul><p>Unlike some solutions, Databricks prices seems to be more complex. Mostly because it&#x2019;s composed of two parts :</p><ul><li><strong>Cloud costs</strong> (for us AWS) so : mostly data transfer, compute and storage</li><li><strong>Databricks usage kind-of-licence aka DBU</strong> (DataBricks Units). This cost mostly follow the compute you put in front of it (the bigger the cluster/server/&#x2026; the bigger you pay). It&#x2019;s a cost per time consumed (per-second to be more precise)</li></ul><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks1.png" width="347" height="222" loading="lazy" alt></div><div class="kg-gallery-image"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks2.png" width="347" height="222" loading="lazy" alt></div></div></div><figcaption><p><span style="white-space: pre-wrap;">You can have a clear correlation between the number of instances and the DBU consumed (in this example, 1 instance = 2 DBU/h)</span></p></figcaption></figure><h2 id="monitor-what-you-pay-and-tag">Monitor what you pay (and tag)</h2><p>Now that you know how the bill will be split...</p><p>For doing this you have multiple options, but the first one you will used is maybe the account console. She allow you to filter your data usage using various graphs. This filter can be done on : SKU, workspace and tags. </p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks3.png" class="kg-image" alt loading="lazy" width="2000" height="1044" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks3.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks3.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks3.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks3.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>While this may not provide precise cost analysis, it is effective initially if your tags are well configured. Because yes, tags is a classical but still relevant best practice regarding FinOps and cost monitor .</p><p>In Databricks some tags are set up by design. But you can also your own tags convention. At Jolimoi all our cloud assets (including Databricks, except endpoints since they didn&#x2019;t allow colons) are setup with the following tag :</p><table>
<thead>
<tr>
<th>Tag</th>
<th>What it means?</th>
</tr>
</thead>
<tbody>
<tr>
<td>jm:application</td>
<td>This is the very basic. Call it feature or something else like project, it&#x2019;s the key identifier regarding the usage of this asset</td>
</tr>
<tr>
<td>jm:domain</td>
<td>Can a division a team or just a business domain (marketing, data and so on)</td>
</tr>
<tr>
<td>jm:role</td>
<td>Example : front, back, security, ETL, data science</td>
</tr>
<tr>
<td>jm:environment</td>
<td>Production, Integration, Staging, Sandbox &#x2026;</td>
</tr>
<tr>
<td>jm:owner</td>
<td>Key stakeholder, project owner, analyst or even a technical contact. In fact whatever you need to identify who is in charge of this asset in term of billing</td>
</tr>
<tr>
<td>jm:managedBy</td>
<td>Mainly to identify how this asset was build. In our case it can be Terraform, CloudFormation or just nothing, which means it was done by hand</td>
</tr>
<tr>
<td>jm:taggingVersion</td>
<td>Even tagging convention can have versions &#x1F604;</td>
</tr>
</tbody>
</table><p>This tags aren&#x2019;t only interesting to understand who used what (and having some more readable information than a cluster ID). These tags are practical for applying show-back and charge-back strategies to other business entities, especially if the IT budget is distributed across the company.</p><p>And to talk again about data usage, they are available via multiple ways :</p><ul><li>API</li><li><a href="https://docs.databricks.com/en/admin/account-settings/billable-usage-delivery.html?ref=tech.jolimoi.com" rel="noreferrer">S3 delivery</a> (preview)</li><li>System tables (preview also, see below)</li></ul><h2 id="systembillingusage">system.billing.usage</h2><p>And so speaking about this last one, if you want to foster this data more accurately you need to used system tables.</p><p>The system tables include:</p><ul><li><code>system.billing.usage</code>: Usage data</li><li><code>system.billing.list_prices</code>: Pricing data for Databricks SKUs at precise times</li></ul><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks5.png" class="kg-image" alt loading="lazy" width="2000" height="2440" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks5.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks5.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks5.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks5.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>If you want to play with this tables Databricks give you a <a href="https://docs.databricks.com/en/admin/system-tables/billing.html?ref=tech.jolimoi.com#sample-queries" rel="noreferrer">list of queries examples and templates</a>.</p><p>However, you might prefer to create your own query, such as this one:</p><pre><code class="language-sql">SELECT 
  billing_origin_product
  , usage_date
  , usage.sku_name
  , COUNT(usage_quantity) as dbu_count
  , CAST(pricing[&quot;default&quot;] AS FLOAT) as pricing
  , (dbu_count * CAST(pricing[&quot;default&quot;] AS FLOAT)) as total_price
  , custom_tags[&quot;jm:application&quot;] as application
FROM system.billing.usage 
INNER JOIN system.billing.list_prices on usage.cloud = list_prices.cloud 
  and usage.sku_name = list_prices.sku_name 
  and usage.usage_start_time &gt;= list_prices.price_start_time 
  and (
    usage.usage_end_time &lt;= list_prices.price_end_time 
    or list_prices.price_end_time is null
    )
GROUP BY 
  billing_origin_product
  , usage_date
  , usage.sku_name
  , pricing[&quot;default&quot;]
  , custom_tags[&quot;jm:application&quot;]
ORDER BY 
  usage_date DESC
  , dbu_count DESC;
</code></pre><p>Or also the cost observability dashboard available on <a href="https://github.com/databricks/tmm/tree/main/System-Tables-Demo/Serverless-Jobs-Notebooks-PuPr?ref=tech.jolimoi.com" rel="noreferrer">Github</a> (not really working well, and in fact why not putting this in the sample gallery? &#x1F604;).</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks6.png" class="kg-image" alt loading="lazy" width="2000" height="1084" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks6.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks6.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks6.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks6.png 2000w" sizes="(min-width: 720px) 720px"></figure><h2 id="optimize-your-compute">Optimize your compute</h2><p>So now let&#x2019;s jump to the compute topic and what can done on Cloud side. Since every option can be related to your specific use cases, I will mainly focus on some global guidance regarding this big topic.</p><p>The first idea is definitely to evaluate instance types and families. For that Databricks help you through the interface and the possibilities are wide :</p><ul><li>Optimized for storage, memory, general purpose, with GPU</li><li>With or without <a href="https://docs.databricks.com/en/optimizations/disk-cache.html?ref=tech.jolimoi.com" rel="noreferrer">Delta cache accelerated</a> (Databricks Runtime 14.2 and above, the&#xA0;<code>CACHE&#xA0;SELECT</code>&#xA0;command is ignored)</li></ul><p>For instance family let&#x2019;s sum up it :</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/image.png" class="kg-image" alt loading="lazy" width="713" height="791" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/image.png 600w, https://tech.jolimoi.com/content/images/2024/06/image.png 713w"></figure><p>If you ask about what EC2 instance refer, the AWS console is always a good start to compare instances:</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks7.png" class="kg-image" alt loading="lazy" width="2000" height="1108" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks7.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks7.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks7.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks7.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>And if you also asked what are all this letters, you can find a quick explanation in <a href="https://docs.aws.amazon.com/ec2/latest/instancetypes/instance-type-names.html?ref=tech.jolimoi.com" rel="noreferrer">this article</a>.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks8.png" class="kg-image" alt loading="lazy" width="2000" height="1406" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks8.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks8.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks8.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks8.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>Apart of general considerations, the best advise is monitor your workload and see how to internals of the cluster (memory and CPU) react to it. Same for the driver node sizing.</p><p>For the Delta cache as explain before, if you&apos;re using the more recent runtime it&apos;s not something you need to look especially. And by the way, picking the latest runtime always seems to come with some good news regarding performances (but always check if your code run on it for sure).</p><p>Also, be careful about Graviton instances they didn&#x2019;t support some features.</p><h2 id="leverage-cloud-capabilities">Leverage Cloud capabilities</h2><p>Not related to Databricks but Cloud provider also offer specific capabilities in order to optimize your bills. In AWS it can be discount with Saving Plans (more flexible with bigger discount) and Reserved Instances (not the best option).</p><p>It&#x2019;s just a engagement for you in regard of AWS : you engage your consumption on a family and in regard of that, AWS will give you a discount. And it&#x2019;s bigger if you pay a part or the total in advance (upfront).</p><p>AWS propose some automatic recommendations based on your past consumption. It&#x2019;s a good start regarding this:</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks9.png" class="kg-image" alt loading="lazy" width="2000" height="1426" srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks9.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks9.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks9.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks9.png 2000w" sizes="(min-width: 720px) 720px"></figure><h2 id="photon-or-not-photon">Photon or not Photon?</h2><p>Last but not least, <a href="https://docs.databricks.com/en/compute/photon.html?ref=tech.jolimoi.com" rel="noreferrer">as define by Databricks</a>, Photon can be see as something cost effective. </p><pre><code class="language-sql">Photon is a high-performance Databricks-native vectorized query engine that runs your SQL workloads and DataFrame API calls faster to reduce your total cost per workload.
</code></pre><p>For sure Photon is maybe for you a no-brainer when your goal is to go quicker like using a Job cluster and made your results go faster before termination. But did you do really the math?</p><p>Because by default, Photon means paying twice the price. It&apos;s as simple as it is. But is Photon reduce your time per 2 also ?</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks10.png" width="2000" height="929" loading="lazy" alt srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks10.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks10.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks10.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks10.png 2000w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://tech.jolimoi.com/content/images/2024/06/dbks11.png" width="2000" height="929" loading="lazy" alt srcset="https://tech.jolimoi.com/content/images/size/w600/2024/06/dbks11.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2024/06/dbks11.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2024/06/dbks11.png 1600w, https://tech.jolimoi.com/content/images/2024/06/dbks11.png 2000w" sizes="(min-width: 720px) 720px"></div></div></div></figure><h2 id="not-yet-a-conclusion">(Not yet a) Conclusion </h2><p>This concludes our discussion on Databricks cost management. We can imagine cover in a future article topics such as job and cluster configuration, auto-termination, pool clusters, fleet and spot instances, and SQL warehouses.</p>]]></content:encoded></item><item><title><![CDATA[Ranking with Databricks]]></title><description><![CDATA[It is not always possible and sometimes does not make sense to assign rankings uniquely ...]]></description><link>https://tech.jolimoi.com/ranking-with-databricks/</link><guid isPermaLink="false">66588fd4900a5c0001c595c5</guid><dc:creator><![CDATA[Martin Labenne]]></dc:creator><pubDate>Thu, 13 Jun 2024 07:27:32 GMT</pubDate><media:content url="https://images.unsplash.com/flagged/photo-1578928534298-9747fc52ec97?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fHJhbmtpbmd8ZW58MHx8fHwxNzE3MDgwMDAxfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/flagged/photo-1578928534298-9747fc52ec97?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fHJhbmtpbmd8ZW58MHx8fHwxNzE3MDgwMDAxfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Ranking with Databricks"><p>When it comes to deal with historical data, it is a common task to work with the most recent and fresh data to perform analysis: that&apos;s where the <em>ranking</em> comes in.</p><p>The rank of an object is defined as a <em>relationship between a set of items such that, for any pair of items, the first is either &quot;ranked higher than&quot;, &quot;ranked lower than&quot;, or &quot;ranked equal to&quot; the second</em>.</p><h1 id="databricks-implementations">Databricks implementations</h1><p>It is not always possible and sometimes does not make sense to assign rankings uniquely. Depending of the use case, some strategies might be better than other. A common shorthand way to distinguish the best ranking strategy for your use-case is by the ranking 4 items:</p><ul><li>The first item ranked ahead</li><li>The second and third, which compare equal (<em>ties</em>)</li><li>The fourth item ranked last</li></ul><p>The object of the different methods is to define the value of the ranking for equal items and items around them.</p><p>Databricks implements 3 ranking strategies.</p><h2 id="standard-competition-ranking-%E2%80%9C1224%E2%80%9D"><strong>Standard competition ranking &#x201C;1224&#x201D;</strong></h2><p>This ranking strategy is frequently adopted for competitions, as items that are equal receive the same ranking number, and the following item rank is its <strong>position</strong> in the ordered list.</p><p>In the competition example, it means that if two (or more) competitors tie for a position in the ranking, the position of all those ranked below them is unaffected.</p><p>Databricks implements this ranking with <code>rank()</code> over subsets of data called partitions.</p><pre><code class="language-sql">SELECT 
    id_runner
  , rank() OVER(PARTITION BY race ORDER BY time_to_finish DESC)
FROM competitions
</code></pre><p>According to the documentation, <code>rank</code> will produce gaps in the ranking sequence but will <em>not</em> break ties.</p><h2 id="dense-ranking-%E2%80%9C1223%E2%80%9D"><strong>Dense ranking &#x201C;1223&#x201D;</strong></h2><p>In dense ranking, items that compare equally receive the same ranking number, and the next items receive the <strong>immediately following</strong> ranking number.</p><p>Databricks implements this ranking with <code>dense_rank()</code> over partitions.</p><pre><code class="language-sql">SELECT 
    id_runner
  , dense_rank() OVER(PARTITION BY race ORDER BY time_to_finish DESC)
FROM competitions
</code></pre><p>According to the documentation, <code>dense_rank</code> will <em>not</em> produce gaps in the ranking sequence and will <em>not</em> break ties.</p><h2 id="ordinal-ranking-%E2%80%9C1234%E2%80%9D"><strong>Ordinal ranking &#x201C;1234&#x201D;</strong></h2><p>This strategy it meant for scenarios where <em>the uniqueness of the rank is required</em>.</p><p>In ordinal ranking, all items receive distinct ordinal numbers, including items that compare equal. The assignment of distinct ordinal numbers to items that compare equal can be done at random, or arbitrarily, but it is generally preferable to use a system that is arbitrary but consistent, as this gives stable results if the ranking is done multiple times.</p><p>Databricks implements this ranking with <code>row_number()</code> over partitions.</p><pre><code class="language-sql">SELECT 
    id_runner
  , row_number() OVER(PARTITION BY race ORDER BY time_to_finish DESC)
FROM competitions
</code></pre><p>According to the documentation, <code>row_number</code> will <em>not</em> produce gaps in the ranking sequence but will break ties.</p><p>If the order is not unique, the result is non-deterministic.</p><p>An example of an arbitrary but consistent system would be to incorporate other attributes into the ranking order</p><h1 id="comparing-methods">Comparing methods</h1><p>Now let&apos;s wrap up everything and compare the methods. It&apos;s up to you to use the one that best fits your needs!</p><pre><code class="language-sql">SELECT 
    id_runner
  , race
  , rank() OVER(PARTITION BY race ORDER BY time_to_finish DESC)
  , dense_rank() OVER(PARTITION BY race ORDER BY time_to_finish DESC)
  , row_number() OVER(PARTITION BY race ORDER BY time_to_finish DESC)
FROM competitions
</code></pre><pre><code>id_runner | race | rank | dense_rank | row_number |
----------|------|------|------------|------------|
        21|     A|     1|           1|           1|
        56|     A|     2|           2|           2|
        87|     A|     2|           2|           3|
        18|     A|     4|           3|           4|
----------|------|------|------------|------------|
        87|     B|     1|           1|           1|
       ...|   ...|   ...|         ...|         ...|
</code></pre><h1 id="sources">Sources</h1><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://en.wikipedia.org/wiki/Ranking?ref=tech.jolimoi.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Ranking - Wikipedia</div><div class="kg-bookmark-description"></div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://en.wikipedia.org/static/apple-touch/wikipedia.png" alt="Ranking with Databricks"><span class="kg-bookmark-author">Wikimedia Foundation, Inc.</span><span class="kg-bookmark-publisher">Contributors to Wikimedia projects</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/50px-Question_book-new.svg.png" alt="Ranking with Databricks"></div></a></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://docs.databricks.com/en/sql/language-manual/functions/rank.html?ref=tech.jolimoi.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">rank ranking window function</div><div class="kg-bookmark-description">Learn the syntax of the rank function of the SQL language in Databricks SQL and Databricks Runtime.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://docs.databricks.com/en/_static/favicon.ico" alt="Ranking with Databricks"><span class="kg-bookmark-author">Databricks</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.databricks.com/wp-content/uploads/2020/04/og-databricks.png" alt="Ranking with Databricks"></div></a></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://docs.databricks.com/en/sql/language-manual/functions/dense_rank.html?ref=tech.jolimoi.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">dense_rank ranking window function</div><div class="kg-bookmark-description">Learn the syntax of the dense_rank function of the SQL language in Databricks SQL and Databricks Runtime.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://docs.databricks.com/en/_static/favicon.ico" alt="Ranking with Databricks"><span class="kg-bookmark-author">Databricks</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.databricks.com/wp-content/uploads/2020/04/og-databricks.png" alt="Ranking with Databricks"></div></a></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://docs.databricks.com/en/sql/language-manual/functions/row_number.html?ref=tech.jolimoi.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">row_number ranking window function</div><div class="kg-bookmark-description">Learn the syntax of the row_number function of the SQL language in Databricks SQL and Databricks Runtime.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://docs.databricks.com/en/_static/favicon.ico" alt="Ranking with Databricks"><span class="kg-bookmark-author">Databricks</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.databricks.com/wp-content/uploads/2020/04/og-databricks.png" alt="Ranking with Databricks"></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Metabase multi-selection filters customization]]></title><description><![CDATA[Unlock Metabase's full potential by optimizing filters. Enhance dynamic analysis and user experience with tailored customizations for key filter types.]]></description><link>https://tech.jolimoi.com/metabase-multi-selection-filters-customization/</link><guid isPermaLink="false">65c0e813900a5c0001c59530</guid><category><![CDATA[metabase]]></category><category><![CDATA[data-visualization]]></category><category><![CDATA[bi]]></category><category><![CDATA[analytics]]></category><dc:creator><![CDATA[Mallhar Bidwaikar]]></dc:creator><pubDate>Mon, 08 Apr 2024 10:19:15 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2024/02/prism.png" medium="image"/><content:encoded><![CDATA[<img src="https://tech.jolimoi.com/content/images/2024/02/prism.png" alt="Metabase multi-selection filters customization"><p>Metabase is a great tool that offers a lot of functionalities, but sometimes I would like to get even more out of the tools I use. In particular, I am talking about filters. While filters are a valuable and essential functionality to perform dynamic analysis, they present some limitations and can lead to confusing situations, diminishing the end user experience. Below, I show a way to tweak and customize 2 types of filters in Metabase to make them perfectly match your user needs!</p><h3 id="limiting-the-number-of-values-in-drop-down-filters">Limiting the number of values in drop down filters:&#xA0;</h3><p>In this case, I want to display the sales which have been made in a subset of countries (let&#x2019;s say 10 countries). In the database there is a table listing every country where we sell products. I would like to use this table to build a dropdown filter for my question and show only countries from the subset I&apos;m interested in, instead of including the whole list. With the method above, the dropdown list will list all countries available from the database. I don&#x2019;t want to scroll to the bottom of the list or type the name every time I want to select France or the UK for example. I want to show only the 10 countries my users are interested in. A solution is to use the available custom dropdown list filter but you have to type the whole list for each new question which alright for a very small list but&#xA0; nonsensical in the world of automation and hence not the optimal solution.</p><p>The most efficient way to use a dropdown filter in Metabase is to make it of the type field filter and map it to the field (in this case country) of the table the data is stored in. Dropdown is not the only categorical filter available in Metabase. Sometimes it&#x2019;s preferable to define a simpler filter, like a string search field or a custom list of strings from a text filter, although multi selection is not available for this kind of filter.</p><p>To solve this problem, we use a dedicated question that lists the countries we are interested in (which we use as a location dimension for other questions).&#xA0;</p><p>There is an easy way to do this in Metabase:</p><ol><li>As usual, we start by making the filter a field filter.</li></ol><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/fEhEPZdmQ6YyChz6g5fELBXjJgYKH-00lSoc7L_uYMpCh7_AH0CIaBZPPSBNDZ5RAOHZokJDXOcaRyigEeAIZ1v-mmHQW3FN4Vmel8PXrBB9Ci-S0-L8zU2WrYzW4RE6pjY7qHocnpxjv5ZAgED-R9nYh1bXbR5RUiOZztK1GMHOxG2SaEXZnwqhCwWBVA" class="kg-image" alt="Metabase multi-selection filters customization" loading="lazy" width="433" height="789"></figure><ol start="2"><li>You will see that the dropdown list contains all the countries that are included in the table. To narrow the available choices, create a new question (or native SQL depending on your requirements) which shows only the list of countries that you want in the dropdown list. Save it in the same place where you will save the main question.</li><li>Click on the <strong>Edit</strong> button that you see on the right side of <strong>Dropdown list</strong> in the image above. Then click on <strong>From another model or question </strong>and select the question you just created which has the list of countries. Select the field (<strong>name </strong>in my case). Click on <strong>Done</strong>.</li></ol><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/eaxo8o--kbPBG6m3-ymYPXA7J84qXE6wBUKs0loIOzllDPTf8ZAQ2vOVcQWjUvRtyEHcfYBxypQw1gM6XBfErx0UdRZB2XZIWVWTP7M0pkpIUkbhpUqTSx365GeiClzBJO8EVRgg5rQHP-c5n4N2CdpbcjoZk493P5evdwQUVjyUkIAE6S4wLF0TnfpoTQ" class="kg-image" alt="Metabase multi-selection filters customization" loading="lazy" width="415" height="471"></figure><ol start="4"><li>Et voil&#xE0;, when I click on the filter, I see only the 10 countries that I&#x2019;ve listed. And I can multi-select!</li></ol><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/UQPQjLuH5Z4Mi3Q5znEpkNYZKStrQSR_zPUbfoxMg53KQ2kMo2h28Knzy5ZgtgiLQeaWF78ZMcLgC-YyY6pMvvOvEpIOgEJwAQ3fOPySxJYZ5loAsId3CF_QtLiEydKB5JCjzHSHuFJnMlX0lsEyI12xXDxMlYmEBcDcclE0Uf5JA1idQa4KVpYDk4g2Rw" class="kg-image" alt="Metabase multi-selection filters customization" loading="lazy" width="423" height="616"></figure><h3 id="adapting-normal-text-filters-to-handle-multiple-comma-separated-values">Adapting normal text filters to handle multiple comma-separated values:</h3><p>Here the data is user created, meaning it does not already exist in this form in the database, so we cannot directly map the filter to a field in a table and make it a dropdown list with multi selection possible (as explained in the previous part).</p><p>This issue can be solved with the FIND_IN_SET function from MySQL 8. The way to make this possible is to use a text filter in which users can&#xA0; type the values they are looking for separated by a comma. Let&#x2019;s say we analyze the sales of the company grouped by the departments in France. We want to allow the user to type, e.g. 11,12,13,14,15 and have the question show the results for these 5 departments. We had to find a way to retrieve each of the data that belongs to one of these departments, which from a technical perspective is the same as looking for the department of each line of the sales table in the set of user provided departments.&#xA0;</p><p>In France, most of the department numbers are defined as the first 2 digits of the postal / zip code (5 digits). In the following I will follow this rule for the sake of simplicity.</p><p><u>Let&#x2019;s define:</u></p><p>&#x1F449;&#xA0;postcode is the field containing the zip code of the customer buying a product from our shop</p><p>&#x1F449;&#xA0;department is the custom field derived from postcode containing the department of the sale</p><ul><ul><li><em>With MySQL 8: LEFT(postcode, 2) AS department&#xA0;</em></li></ul></ul><p>&#x1F449;&#xA0;{{departments}} is the filter of type text (input box format) that can receive multiple department numbers separated by a comma</p><p>The function FIND_IN_SET of MySQL 8 takes two parameters and returns the position of the 1st parameter (the string to find) in the 2nd parameter (a set of comma separated strings).&#xA0; If the 2nd parameter doesn&#x2019;t contain the first parameter, the function returns 0.</p><p>The idea is to find the value of the department&#xA0; in {{departments}}. If it is not found, FIND_IN_SET will return 0. Thus, I just had to slice the results of my query with the following condition:&#xA0;&#xA0;</p><p><strong><em>FIND_IN_SET(LEFT(postcode, 2), {{departments}}) &gt; 0</em></strong></p><p>As we can see below, we get exactly the 3 departments typed in the filter. There is no limit to the number of departments we can type in one go.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/_1DVBCPnq4w0ENATef3_aHqZE6uNTFb3uJxfb7vFw5x8wpkV4jK1gTVBIY8nkcDoItD2f9Sg3I5bzQ46vJM7Jwu8IPxzvQcoe7fQ7g18fwZ7bDszkq6PqdegdFa2pND9JGkph4EB8VQr9l7blok6KCGPdsnhChDo6zbP06Whw5ITEMH-VL_w0GwqYve6cQ" class="kg-image" alt="Metabase multi-selection filters customization" loading="lazy" width="594" height="298"></figure><p>A limitation, however, is that the string in which the search is performed has to be comma separated. If for some reason, the users want another type of string delimiter for the filter, FIND_IN_SET will not work. You could use REGEXP or declinations of this function to solve this problem.</p><p>Another limitation of this technique is that the user has to know all the classes of the data set in order to access full information: the classes are not listed in a dropdown list and the users can forget one in their analysis.&#xA0;&#xA0;</p><p>And that is how we can tweak these 2 types of filters in Metabase to make them show us what we want. It&#x2019;s a little bit of work, but it works!</p><h3 id="references">References:</h3><p><a href="https://www.metabase.com/docs/latest/questions/native-editor/sql-parameters?ref=tech.jolimoi.com#field-filter-syntax">https://www.metabase.com/docs/latest/questions/native-editor/sql-parameters#field-filter-syntax</a></p><p><a href="https://www.metabase.com/learn/sql-questions/field-filters?ref=tech.jolimoi.com">https://www.metabase.com/learn/sql-questions/field-filters</a></p><p><a href="https://dev.mysql.com/doc/refman/8.0/en/string-functions.html?ref=tech.jolimoi.com#function_find-in-set">https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_find-in-set</a></p><p>https://dev.mysql.com/doc/refman/8.0/en/regexp.html</p>]]></content:encoded></item><item><title><![CDATA[Firebase]]></title><description><![CDATA[A brief introduction to Firebase, its features, pricing, drawbacks, comparison of its real-time db with other No-SQL DBs and how we utilize Firebase in our organisation. ]]></description><link>https://tech.jolimoi.com/firebase/</link><guid isPermaLink="false">655dd8d2f84d1c00013a55dc</guid><dc:creator><![CDATA[Mouleeswaran Ganapathi]]></dc:creator><pubDate>Thu, 18 Jan 2024 13:12:04 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2023/11/firebase.png" medium="image"/><content:encoded><![CDATA[<h3 id></h3><img src="https://tech.jolimoi.com/content/images/2023/11/firebase.png" alt="Firebase"><p>Firebase is a <strong>BaaS</strong> (Backend as a Service) platform for building mobile and web applications. It was founded in 2011 by Andrew Lee and James Tamplin as a platform to help developers build web and mobile applications without worrying about infrastructure. Initially, the platform offered a real-time database, authentication, and hosting features. Google then acquired the platform in 2014, which helped its growth and development, with the continued expansion of its range of services. It is a simple and user-friendly platform that doesn&#x2019;t require complex configuration.&#xA0;</p><p>Some of the features of firebase are</p><ul><li>Real-time database,&#xA0;</li><li>Firestore,</li><li>Authentication,</li><li>Cloud storage,</li><li>Cloud Messaging</li><li>Cloud Functions,&#xA0;</li><li>Crash Reporting,</li><li>Analytics,</li><li>Hosting.</li></ul><p><strong>Realtime Database</strong>: It is a NoSQL cloud-hosted database that allows to store data and sync across multiple clients or devices in real-time.</p><p><strong>Firestore</strong>: It is an advanced NoSQL cloud-hosted database with real-time synchronization, powerful querying capabilities, and offline support.</p><p><strong>Authentication</strong>: It provides a simple and secure way to authenticate users with&#xA0;</p><ul><li>email and password,&#xA0;</li><li>social media logins,</li><li>custom authentication.</li></ul><p><strong>Cloud Storage</strong>: It provides scalable and secure cloud storage for files including media files.</p><p><strong>Cloud Messaging</strong>: It allows sending notifications, data messages, and messages with both notification and data payloads to users on different platforms.</p><p><strong>Cloud Functions</strong>: It allows developers to write serverless functions in JavaScript that can be triggered by events in your app or other Firebase services.</p><p><strong>Hosting</strong>: It provides fast and secure static hosting for your web app, with automatic SSL encryption and CDN integration.</p><p><strong>Analytics</strong>: It provides insights into user interactions with your app, including behavior, demographics, and more.</p><p><strong>Crash Reporting</strong>: Firebase&apos;s Crash Reporting service helps developers identify and fix crashes and errors quickly and easily.</p><h3 id="pricing"><strong>Pricing</strong></h3><p>Firebase offers a range of pricing options, with a free tier for those getting started with the platform. Paid plans are available for those who require additional storage, bandwidth, or features.</p><h3 id="free-tier-real-time-database-limitations"><strong>Free tier Real-time database limitations</strong></h3><ul><li>100 Simultaneous connections</li><li>1 GB of storage</li><li>10 GB/month of data download</li><li>No multiple databases per project</li></ul><h3 id="drawbacks"><strong>Drawbacks</strong></h3><p>While the platform offers numerous benefits, it does have some drawbacks to consider.&#xA0;</p><p><strong>Limited Querying</strong>: The real-time db doesn&#x2019;t support complex querying like SQL databases. For complex querying, additional data processing is required on the client side. This can be overcome by using Firestore which provides advanced query handling.&#xA0;</p><p><strong>Vendor Lock-In</strong>: Locked into using Google&#x2019;s services. Hard to migrate to another platform which requires a lot of work.</p><p><strong>Cost</strong>: It can be expensive for Large applications and high-traffic websites.&#xA0;</p><h3 id="firebase-real-time-db-vs-other-nosql-dbs"><strong>Firebase Real-time DB vs other NoSQL DBs</strong></h3><p>Let&#x2019;s compare the real-time NoSQL db provided by Firebase with other NoSQL dbs like Amazon DynamoDB, Cassandra, Couchbase, and MongoDB based on the following parameters.&#xA0;</p><p><strong>Data Model</strong>: The way data is structured, stored, and accessed&#xA0;</p><p><strong>Real-time Synchronization</strong>: The ability to update data across multiple clients in real-time.</p><p><strong>Data Scalability</strong>: The ability to handle increasing amounts of data&#xA0;</p><p><strong>Data Querying</strong>: Process of retrieving the data from db</p><p><strong>Hosting &amp; Management</strong>: The way the db is made available and managed.<br></p><table style="border:none;border-collapse:collapse;"><colgroup><col width="128"><col width="115"><col width="130"><col width="115"><col width="126"><col width="129"></colgroup><tbody><tr style="height:50.888260434570306pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:bottom;background-color:#ffffff;padding:-23.832pt -23.832pt -23.832pt -23.832pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;text-align: center;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Feature</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:bottom;background-color:#ffffff;padding:-23.832pt -23.832pt -23.832pt -23.832pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;text-align: center;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Firebase Realtime Database</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:bottom;background-color:#ffffff;padding:-23.832pt -23.832pt -23.832pt -23.832pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;text-align: center;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Amazon DynamoDB</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:bottom;background-color:#ffffff;padding:-23.832pt -23.832pt -23.832pt -23.832pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;text-align: center;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Cassandra</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:bottom;background-color:#ffffff;padding:-23.832pt -23.832pt -23.832pt -23.832pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;text-align: center;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Couchbase</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:bottom;background-color:#ffffff;padding:-23.832pt -23.832pt -23.832pt -23.832pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;text-align: center;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">MongoDB</span></p></td></tr><tr style="height:124.75pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Data model</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">JSON-based NoSQL database</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Key-value and document-based NoSQL database</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Column-family NoSQL database</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Document-based NoSQL database</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Document-based NoSQL database</span></p></td></tr><tr style="height:106.75pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Real-time synchronization</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Yes, out of the box</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Requires third-party tools or custom code</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Requires third-party tools or custom code</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Yes, through XDCR</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">No out of the box support, requires custom implementation</span></p></td></tr><tr style="height:52.75pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Data scalability</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Horizontally scalable</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Horizontally scalable</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Horizontally scalable</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Horizontally scalable</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Horizontally scalable</span></p></td></tr><tr style="height:160.75pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Data querying</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Basic querying capabilities, requires additional processing on the client-side</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Powerful querying language and indexing options</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Powerful querying language</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Powerful querying language</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Powerful querying language</span></p></td></tr><tr style="height:142.75pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hosting and management</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Fully managed and hosted by Google</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Fully managed service provided by Amazon Web Services</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Can be self-hosted or managed through third-party tools</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Can be self-hosted or managed through Couchbase Cloud</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:middle;background-color:#ffffff;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:2.057148;margin-top:19pt;margin-bottom:19pt;"><span style="font-size:9.5pt;font-family:Montserrat,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Can be self-hosted or managed through third-party tools or MongoDB Atlas</span></p></td></tr></tbody></table><h3 id="how-we-utilize-firebase"><strong>How we utilize Firebase&#xA0;</strong></h3><p>We utilize Firebase in our organization in the following ways.</p><p><strong>Authentication: </strong>To authenticate users in one of our applications using email and password.</p><p><strong>Notifications: </strong>To send notifications to users in our application across multiple platforms&#xA0;</p><p><strong>Firebase Queue: </strong>To manage events between micro-services</p><p><strong>Maintenance: </strong>To manage the application. With the change of a property, the application can be put in maintenance mode.<strong>&#xA0;</strong></p><p><strong>Feature Flags: </strong>To enable or disable a specific functionality of an application.&#xA0;</p><p><strong>Force refresh App: </strong>To force refresh the application for all active users at a time.&#xA0;</p><h3 id="overview"><strong>Overview</strong></h3><p>Firebase is an excellent platform for quickly and easily building high-quality, scalable mobile and web applications. With its range of powerful features and easy-to-use tools, it is a popular choice for many around the world including us.&#xA0;</p><h3 id="alternative-baas-platforms"><strong>Alternative BaaS platforms</strong></h3><p>If Firebase hasn&#x2019;t impressed you yet, there are numerous BaaS platforms out there you can check out. Some of them are,</p><p><strong>AWS Amplify</strong>: Amazon&apos;s BaaS platform that offers data storage, user authentication, and more.</p><p><strong>Backendless</strong>: A BaaS platform that offers data storage, user authentication, and serverless functions.</p><p><strong>Kinvey</strong>: A BaaS platform that offers data storage, user authentication, and serverless functions, as well as integrations with various third-party services.</p><p><strong>Parse</strong>: An open-source BaaS platform that offers data storage, user authentication, and serverless functions.</p>]]></content:encoded></item><item><title><![CDATA[Product Vision, Product Strategy and Business Objectives]]></title><description><![CDATA[Why is it crucial for companies to ensure that their product vision, product strategy, and business objectives are in perfect harmony when striving to develop products that truly resonate with customers? This article delves into the significance of this alignment.]]></description><link>https://tech.jolimoi.com/product-vision-product-strategy-and-business-objectives/</link><guid isPermaLink="false">654a5bb1f84d1c00013a555f</guid><dc:creator><![CDATA[Soroush Motlagh]]></dc:creator><pubDate>Wed, 20 Dec 2023 13:01:52 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2023/11/vision-strategy-objectives.jpg" medium="image"/><content:encoded><![CDATA[<div class="kg-card kg-callout-card kg-callout-card-purple"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">The Product Team needs to have the necessary business context; a solid understanding of where the company is heading and a solid understanding of how their team is supposed to contribute to the larger purpose.</div></div><h3 id="business-context">Business context</h3><img src="https://tech.jolimoi.com/content/images/2023/11/vision-strategy-objectives.jpg" alt="Product Vision, Product Strategy and Business Objectives"><p>Business context has two components:</p><ol><li>The product vision and strategy</li></ol><p>The product vision describes the future we are trying to create, typically somewhere between two and five years out. The product vision is one of our most effective recruiting tools, and it serves to motivate the people on your teams to come to work every day.</p><p>The product strategy is our sequence of products or releases we plan to deliver on the path to realizing the product vision.</p><p>Product vision and strategy describe the big picture of what the organization as a whole is trying to accomplish and the plan for achieving that vision.</p><ol start="2"><li>The business objective</li></ol><p>This describes the specific, prioritized business objectives for (each) product team. Tell the team what you need them to accomplish and how the results will be measured, and let them figure out the best way to solve the problems.</p><p><br>It is the management&#x2019;s responsibility to provide each product team with the specific business objectives they need to tackle. The difference is that the product team is now prioritizing business results, rather than product ideas.</p><p>The advantage of this way of working is that the teams are much more motivated when they are free to solve the problem the best way they see fit. Teams are designed to be in the best position to solve these problems and it is all about outcome rather than output.</p><h3 id="product-strategy">Product Strategy</h3><p>To illustrate what is defined by Management and what is defined by the Product take a look at the Product Strategy Stack in the image below. Tops down from mission to product goals all the effort is on correctly defining, planning and alignment on the execution plan; creating any good products or leading any company well without having a clearly defined mission and how to reach these objectives i.e. company and product strategy is not possible. Bottoms up is evaluation; communicate the status of execution,&#xA0; the relatedness and success of the product by tracking how well the product is reaching defined organization&#x2019;s business objectives.</p><p></p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Vm43AJekr7wHPEaFSlWP2o-CaN3-EsPruHRiX_P_MzOxP-Xcf8fh7Dqr9X2e8N3CbUyFyG7AWyu5HSqqc2mOW-q4xMxgqJH943tXHY159I3FqEJKXqRywVyASLQ9WwodVAc3FHvkpFRaRdNRCakzXf8" class="kg-image" alt="Product Vision, Product Strategy and Business Objectives" loading="lazy" width="625" height="352"></figure><p>Source: <a href="https://www.reforge.com/blog/the-product-strategy-stack?ref=tech.jolimoi.com">Reforge</a></p><p></p><p>Building on Product Strategy Stack, an example of Product Strategy / Business Objectives and how it will be translated into Product is explained in the following. This illustrates the definition and evaluation importance. Airbnb had the mission to serve the people who want to rent mattresses in someone else&#x2019;s house. Airbnb took the strategy of showing pictures of the rental places to attract more views and conversions. So the product enabled the feature and it was tracked initially, with an alarming behavior! Pictures were too poor in quality when uploaded by owners, so to meet the objective of conversions, founders hired professional photographers to take high-quality pictures to put on the website. The result was that the product feature was appreciated better and conversions increased exponentially for Airbnb.</p><h3 id="product-development-hierarchy">Product Development Hierarchy</h3><p>Getting it more practical and zooming into the Goals and how they are broken down to User stories, the image below illustrates the Product Development Hierarchy with an example of an online streaming platform. Here, a possible goal in the context of the product is illustrated.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh7-us.googleusercontent.com/Ix0R6ndSYj44WjYRBJjiGlS0CM6hTviW35R-_18LiKxXhnPkgTnoVU0DK4Ys42u9hQjV55ocgBQ_Ed5mSuMOka19obWs-duYq4TUfnuJTs5Iq9RWsjKoj-rD7PbAu45PcDshlxgLEj664jhkQZFX7RQ" class="kg-image" alt="Product Vision, Product Strategy and Business Objectives" loading="lazy" width="624" height="504"><figcaption><span style="white-space: pre-wrap;">Product Development Hierarchy</span></figcaption></figure><p>Goals are what you want to achieve to meet your short term or long term <strong>vision</strong> and Initiatives are the high-level efforts that will help you achieve your goals. Success of an initiative, depending on the context of it can be measured by: objectives of initiative being met and the benefits are measurable, quality is met or exceeded the expectation, customers are satisfied, the budget for completion is well respected and support for initiative is well planned.</p><h3 id="alignment-of-product-vision-product-strategy-and-business-objectives">Alignment of Product Vision, Product Strategy and Business Objectives</h3><p>Marty Cagan emphasizes in his book, INSPIRED, the importance of aligning product vision, product strategy, and business objectives in order to create products that customers love. He argues that without a clear product vision, product strategy, and business objectives, companies will lack the focus needed to create products that truly meet the needs of their customers.</p><p>Cagan emphasizes the need to ensure that the product vision, product strategy, and business objectives are closely linked in order to ensure that the product being created aligns with the company&apos;s overall goals and objectives. Cagan argues that a successful product requires a clear understanding of the customer needs and an effective product strategy that is tailored to meet those needs.</p><h3 id="conclusion">Conclusion</h3><p>To conclude, for a product team to be empowered and act with a meaningful degree of autonomy:</p><ul><li>The team must have a deep understanding of the broader context. [product vision to inspire and set direction, and product strategy to get there];</li><li>Clarity from leadership on the critical pieces of context; lack of clarity raises problems and leads to ambiguity over what a team can decide and what they can&#x2019;t.</li><li>Tell the team what you need them to accomplish and how the results will be measured, and let them figure out the best way to solve the problems.</li></ul><hr><p>Resource: INSPIRED: How to Create Tech Products Customers Love by Marty Cagan</p>]]></content:encoded></item><item><title><![CDATA[HTTP Request cancellation]]></title><description><![CDATA[<p>In today&#x2019;s digital age where internet applications and services are flooding the market, ensuring a seamless user experience is crucial. IT applications rely heavily on networking to collect vital information and strong networking support is key for productivity. Therefore for developers, understanding the lifecycle of networking requests is</p>]]></description><link>https://tech.jolimoi.com/http-request-cancellation/</link><guid isPermaLink="false">655614e9f84d1c00013a55ba</guid><dc:creator><![CDATA[Arnaud Njoh]]></dc:creator><pubDate>Wed, 13 Dec 2023 09:30:26 GMT</pubDate><content:encoded><![CDATA[<p>In today&#x2019;s digital age where internet applications and services are flooding the market, ensuring a seamless user experience is crucial. IT applications rely heavily on networking to collect vital information and strong networking support is key for productivity. Therefore for developers, understanding the lifecycle of networking requests is extremely important. Consider Alice and Bob, two typical internet users facing an often-overlooked issue: HTTP request cancellation. This article dives into that concept, describing a powerful tool that simplifies web application usage and boosts efficiency.</p><h4 id="alice-and-bob-watching-a-movie-on-a-popular-streaming-site">Alice and Bob watching a movie on a popular streaming site:</h4><p>Alice: Hey Bob, I don&#x2019;t like this movie. Can you put the new movie by Antonio Ban&#x2026; ?</p><p>Bob: Ok! Alice, the website is too slow, I cannot navigate through pages.Alice: Maybe it is an internet issue. Let&#x2019;s call the internet provider.</p><p>Alice and Bob during important meetings with investors</p><p>Alice: Please, Bob, can you open the page where we can see recent KPIs of sales?</p><p>Bob: Yes, sure! Can you remind me of the path to reach this KPI?</p><p>Alice: Of course, go to the Dashboard, then click on the blue button with the arrow up icon located in the top-right corner of the page. You should see a pop-up with a list of articles. Select the most recent one then click on the button &#x201C;visualize&#x201D; and then &#x2026;</p><p>Bob: Stop, Alice! You are speaking too fast. I cannot follow. I am still in Dashboard and the app seems to be too slow. Probably an internet issue.</p><p>Alice: Ok, I am writing to the technical department, so they can take a look.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/11/giphy--1-.gif" class="kg-image" alt loading="lazy" width="450" height="379"></figure><h2 id="context">Context</h2><p>These two stories have a concealed common point. And NO, it&#x2019;s not an internet issue. The two web applications are retrieving a heavy set of data when components are attached to the page view and when each component gets unmounted, the fetch actions keep processing by the apps. </p><p>Fetching data, and not rendering it or keeping it for future purposes, is not an effortless job for our Web applications. In fact, at this point, it becomes unpleasant for the Browser to process a lot of data, which might be buggy, and ask to force close some tabs or just crash. So it seems meaningless to reclaim a remote resource if we do not need it.</p><p>So the question now is, how can we prevent our Web applications from fetching not needed set of data? There are plenty of answers to that question, and we will not be focusing on all of them. One of these solutions caught our attention: Request cancellation.</p><h2 id="what-is-an-http-request-cancellation">What is an HTTP Request Cancellation</h2><p>Looking at the way HTTP protocol is designed, it is almost impossible to break off an emitted HTTP Request; especially on the server side of our Web application. In most cases, when a server is done processing a request, it pushes a response to the emitter or the client; which in turn performs some operations with the obtained data.&#xA0;</p><p>What will the client do if the received data is no longer needed at the time of response? It will still process them even if the data are volatile information. So, the cost will be the use of a CPU and/or any other type of memory.&#xA0; This probably doesn&apos;t mean much for simple and light requests. But it&apos;s a different story for the more memory-intensive, heavy calls.</p><p>So, the objective of canceling an ongoing HTTP request is therefore to prevent the transmission of the response and its analysis or reading in the client&apos;s memory.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/11/giphy.gif" class="kg-image" alt loading="lazy" width="920" height="563" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/11/giphy.gif 600w, https://tech.jolimoi.com/content/images/2023/11/giphy.gif 920w" sizes="(min-width: 720px) 720px"></figure><h2 id="how-request-cancellation-works">How Request Cancellation works?</h2><p>Request Cancellations are possible using an interface named <strong>AbortSignal.&#xA0;</strong></p><p><strong>Signals</strong> is an event-driven programming paradigm that enables developers to create custom events and event listeners using JavaScript. This means that they can trigger callbacks or functions when certain events occur within their application, such as user input or data changes<strong>.&#xA0;</strong></p><p>The<strong> AbortSignal</strong> interface represents a signal object that allows you to communicate with a <strong>DOM</strong> request and abort it if necessary using an <strong>AbortController</strong> object.&#xA0;</p><p>On the other hand, an <strong>AbortController</strong> instance is used to terminate Web Requests through the <strong>DOM</strong>. The controller has a properly named signal, which is a read-only property that returns an AbortSignal object instance and can be used to communicate with/abort a <strong>DOM</strong> request.</p><h3 id="vanilla-implementation-of-request-cancellation">Vanilla implementation of Request Cancellation</h3><pre><code class="language-Javascript">const controller = new AbortController();

function doVanillaRequest() async {
  const response = await fetch(&apos;/users/kpi&apos;, {
    signal: controller.signal
  });
}

// TODO response handler
// cancel the request
controller.abort()
</code></pre><h3 id="axioss-implementation-of-request-cancellation">Axios&apos;s implementation of Request Cancellation</h3><pre><code class="language-Javascript">const controller = new AbortController();

function doAxiosResquest() async {
  const response = await axios.get(&apos;/users/kpi&apos;, {
    signal: controller.signal
  }); // proceed the response
}

// TODO response handler
// cancel the request
controller.abort()
</code></pre><h2 id="conclusion">Conclusion</h2><p>To sum up, <strong>Request Cancellation</strong> is a practice that completes the lifecycle of an HTTP request. Among other things, it allows us to decide when a request becomes obsolete for the proper functioning of our web applications. It&apos;s also important to know that this pattern may only be used for some requests, as the connection between signals and the DOM is not free, although most current web browsers optimize it.</p><p>Bob: Alice, the internet is back! &#x1F604;</p><p>Alice: Nice! Let&#x2019;s continue.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/11/giphy--2-.gif" class="kg-image" alt loading="lazy" width="380" height="289"></figure><h4 id="sources">Sources</h4><p><a href="https://axios-http.com/docs/cancellation?ref=tech.jolimoi.com">https://axios-http.com/docs/cancellation</a></p><p><a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController?ref=tech.jolimoi.com">https://developer.mozilla.org/en-US/docs/Web/API/AbortController</a>&#xA0;</p><p><a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal?ref=tech.jolimoi.com">https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal</a>&#xA0;</p><p></p>]]></content:encoded></item><item><title><![CDATA[Which logging library to use in Node.js application]]></title><description><![CDATA[In software development, logs are the place where we will keep track of the history of actions done on an application and where error messages and stack traces will be written.
[...]
This article will explore best practices for effectively managing logs within a Node.js application.]]></description><link>https://tech.jolimoi.com/which-logging-library-to-use-in-node-js-application/</link><guid isPermaLink="false">64ac3ec849630a03d967bee5</guid><dc:creator><![CDATA[Paul Fayoux]]></dc:creator><pubDate>Wed, 29 Nov 2023 09:14:17 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-image-card kg-width-full"><img src="https://tech.jolimoi.com/content/images/2023/09/logs.png" class="kg-image" alt loading="lazy" width="1114" height="484" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/09/logs.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2023/09/logs.png 1000w, https://tech.jolimoi.com/content/images/2023/09/logs.png 1114w"></figure><h2 id="introduction">Introduction</h2><p>&#x201C;Log&#x201D;, a shortening of &#x201C;Logbook&#x201D; make reference to the place sailors were originally writing records of observations and in particular the ship&#x2019;s speed. At that time they were measuring the speed with a <a href="https://en.wikipedia.org/wiki/Chip_log?ref=tech.jolimoi.com">chip log</a> giving its name to the book.</p><p>In software development, logs are the place where we will keep track of the history of actions done on an application and where error messages and stack traces will be written.</p><p>This part should not be neglected because it can really help to understand bugs, and it can provide a lot of important information to understand what was done on the application.</p><p>This article will explore best practices for effectively managing logs within a Node.js application. We&apos;ll begin by defining the expectations for a logging system, delve into security considerations related to logging, and finally, explore key libraries commonly employed for logging purposes.</p><p><strong>TL;DR</strong></p><ul><li>Understand log expectations and utilize log levels for effective logging.</li><li>Exercise caution when logging data, especially sensitive information.</li><li>Choose suitable storage locations and implement log rotation for efficient log management.</li><li>Optimize log performance to prevent application slowdowns.</li><li>Prioritize log security to protect against unauthorized access.</li><li>Consider decentralized log management systems for enhanced security and monitoring.</li><li>Leverage logs for monitoring, error detection, and debugging in web applications.</li><li>Choose a logging library that best fits your specific logging needs.</li></ul><h2 id="what-to-expect-from-a-logging-library">What to expect from a logging library</h2><h3 id="log-level">Log Level</h3><p>In general, we will want to log different types of information, starting with the error that could happen, any status on a process, actions triggered by a user, and any information useful for debugging, &#x2026;</p><p>The things that can be logged are numerous, it will depend on our use case. However, not all those things will require the same attention.</p><p>For that reason, we generally want to use different log levels. That&#x2019;s why most loggers offer the possibility to specify which level of log should be used amongst: error, warn, info, debug, and trace.</p><h3 id="what-to-not-log">What to not log?</h3><p>While it&apos;s possible to log a wide range of information, it&apos;s crucial to exercise extreme caution and avoid logging certain sensitive data. For instance, when recording a user&apos;s connection to an application, it&apos;s imperative to ensure that their password and any other private information are never included in the log files under any circumstances.</p><p>So you must be very careful about what data you are actually logging. In some cases, it can also be nice to use redaction tools to automatically hide sensitive information. You can configure such tools to automatically detect and hide sensitive information before it&#x2019;s written in the log file. Some logging library like <a href="https://github.com/pinojs/pino/blob/master/docs/redaction.md?ref=tech.jolimoi.com">Pino.js</a> allow to do this.</p><h3 id="where-do-we-write-logs">Where do we write logs?</h3><p>When dealing with scripts or command-line interfaces (CLIs), it&apos;s essential to employ a logger to display information in the console, either through the standard output (stdout) or standard error (stderr) streams. This approach allows the user to promptly view any errors or prompts in their terminal and offers the flexibility to redirect the output to a designated file.</p><p>You might be familiar with the redirection:</p><pre><code>node script.js &gt;&gt; output.log 2&gt;&gt; error.log
</code></pre><p>Similarly, when dealing with an application, it will be mandatory to direct your logs to a specific log file for later reference.</p><p>As a general guideline, it&#x2019;s not advised to have a single log file to store the entire historical log data from the initial application launch. As your application runs over time, an increasing volume of log data is generated. If all this data were stored in a single file, it could rapidly expand to occupy gigabytes of space on your server. In extreme cases, this accumulation of data could even lead to server crashes due to insufficient disk space.</p><p>The solution is rather simple: we implement log rotation. This means that when a log file reaches a specified size, it is compressed, and a new log file is created to record the latest log entries. This approach ensures that older log files occupy less space when archived. On linux system that&#x2019;s possible to achieve this with <a href="https://linuxconfig.org/logrotate?ref=tech.jolimoi.com">logrotate</a>.</p><h3 id="performance-considerations">Performance considerations</h3><p>As any I/O operations can have performance impacts, writing logs can be a source of slowness. When trying to write any log on a resource (like a log file), that resource will be locked until the writing operation has been completed. It means that if your application is trying to create a lot of logs it can have a lot of latency because it&#x2019;s actually waiting for the logs to be written.</p><p>In an ideal logging system, any log operation should not have any impact on the performance of your application. So we will want our logging system to use the minimum amount of resources, to avoid having any throttling effect.</p><p>We must consider that Node.js is single-threaded, so if log operations are handled on the same process it could lead to performance issues. The event loop could be overloaded with log operation, and spend most of the execution time writing some logs instead of doing something else.</p><p>So the best would be to have another process that handles log writing, in most logging libraries those log processors are called transport.</p><h3 id="protecting-your-logs">Protecting your logs</h3><p>Logs are typically the initial point of examination in the event of a server or application attack. They encompass a record of all system operations, making them the primary source for forensic analysis. If a malicious actor gains access to the logs, they may attempt to delete them to conceal their actions, that&#x2019;s why it is imperative to ensure the robust protection of logs.</p><p>Thereby, when considering log storage, it&apos;s essential to choose wisely where to store them. If you&#x2019;re managing a web application hosted on a server, it&#x2019;s generally not advisable to store the logs on the same server where the application is running.</p><p>To protect the log even more, we will want to avoid any writing operation that could override the log content.</p><p>That&#x2019;s where having a decentralized log management system comes into play. There are a lot of solutions available on the market. If you are a user of Amazon Web Services you might be aware of <a href="https://aws.amazon.com/fr/cloudwatch/?ref=tech.jolimoi.com">CloudWatch</a>. At Jolimoi we are also using <a href="https://newrelic.com/fr?ref=tech.jolimoi.com">Newrelics</a>. Using a decentralized log management system will make sure your logs are safe and easy to monitor.</p><h3 id="monitor-logs">Monitor logs</h3><p>If you are overseeing a web application or a service that necessitates monitoring, logs can be handy.</p><p>Modern monitoring tools rely on logs from your application to detect and track any occurring errors. With proper configuration, these tools can promptly identify outages and correlate them with the specific error entries in the logs. This capability significantly expedites the process of pinpointing the error&apos;s source and aids in swiftly devising solutions to rectify it. In this aspect <a href="https://newrelic.com/fr?ref=tech.jolimoi.com">Newrelics</a> offers advanced error tracking features, and <a href="https://www.datadoghq.com/?ref=tech.jolimoi.com">Datadog</a> provides similar capabilities.</p><h2 id="basic-logging-in-javascript">Basic logging in Javascript</h2><p>If you know about Javascript, you must know about <code>console.log()</code>. That&#x2019;s the default way to log something in Javascript.</p><p>If running the Javascript code on a browser, with <code>console.log()</code> you will have access to the browser <code>console</code>. So the Console API will depend on the implementation of the browser.</p><p>Currently, there is no standardization of the implementation of the console by browser, most of them provide similar API, but implementation can vary.</p><p>For example, you can have different results while running this piece of code in different browsers:</p><p>If running this on Chrome you will have the following result:</p><figure class="kg-card kg-image-card"><img src="https://lh4.googleusercontent.com/H3ivdmEBIiM3Z-5TIcN7KwNnbquYO6mwR3TRrVoGX65oX7GHCULRftxnIuUN998hfE289xqcSI3FPQhFP2NMVB9mq-y9HssvxYl-aBGbfLvJ9VFQNWiZ6nwebA2CfEAD_FlS4dYG753jnxNBTXI70Jk" class="kg-image" alt="Inside a Chrome console, typing the following code : &quot;class Test{ constructor(name) {this.name = name}}; console.log(new Test(&apos;test&apos;))&quot; will produce the following output : &quot;Test { name: &apos;test&apos;&#xA0;}}&quot;" loading="lazy"></figure><p>While if you run that in Firefox you will get this:</p><figure class="kg-card kg-image-card"><img src="https://lh6.googleusercontent.com/jJ5aeMjxM537N2HFlmV2fUbyoereZG8KQfJyjfCH9js3bvqBOipRJ7MYTA13R28g_YbHkO9bETVZ4HKwU8mhLYkcOR9YH6S-aeckFs4vLqxBnm-QuQhrOUtufV3g5u_bZPHTl3-OuFVZpg-ynA9AtlU" class="kg-image" alt="Inside a Firefox console, typing the following code: &quot;class Test{ constructor(name) {this.name = name }}; console.log(new Test(&apos;test&apos;))&quot; will produce the following output: &quot;Object { name: &quot;test&quot; }&quot;" loading="lazy" width="670" height="50"></figure><p>So if you are using advanced features of the console you might check if those are compatible with every browser.</p><p>If you are running the Javascript code on Node.js, you will have access to the <a href="https://nodejs.org/api/console.html?ref=tech.jolimoi.com">Node.js console</a>. By default, those logs will be sent to the standard output.</p><p>Both Browser and Node.js implementations provide <code>console.log()</code>, <code>console.debug(),</code> <code>console.warn()</code>, <code>console.error()</code>, &#x2026; and it can be interesting to use that:</p><ul><li>In the browser if you want to help the developer find the source of some error that could have happened on the front.</li><li>In a Node.js script if you don&#x2019;t have specific needs for performance and if you only need to give feedback to the person that launches the scripts.</li></ul><p>As stated in the Node.js <a href="https://nodejs.org/api/console.html?ref=tech.jolimoi.com#console"><code>Console</code></a> module documentation, it is designed to &quot;provides a simple debugging console&quot; making it well-suited for debugging purposes. However, given the considerations we&apos;ve discussed earlier, using the Node.js console API as a production log system for an application is not advisable.</p><h2 id="which-logging-library-to-use">Which logging library to use?</h2><p>So what logging library should we use that would be acceptable for production?</p><p>On the most used library, we can find small logging libraries that just give the basic logging feature, amongst them you can find <a href="https://www.npmjs.com/package/bunyan?ref=tech.jolimoi.com">Bunyan</a>, <a href="https://www.npmjs.com/package/bole?ref=tech.jolimoi.com">Bole</a>, <a href="https://www.npmjs.com/package/npmlog?ref=tech.jolimoi.com">npmlog</a>, &#x2026; But those don&#x2019;t provide any transports that would make it easy to send logs somewhere else.</p><p>Then you can find <a href="https://github.com/pinojs/pino?ref=tech.jolimoi.com">Pino</a> and <a href="https://github.com/winstonjs/winston?ref=tech.jolimoi.com">Winston</a>, which provide a lot of transport and make it really easy to send logs to different services. You can see <a href="https://github.com/winstonjs/winston/blob/master/docs/transports.md?ref=tech.jolimoi.com#winston-core">the list of transports bundled with Winston</a>, and <a href="https://github.com/pinojs/pino/blob/master/docs/transports.md?ref=tech.jolimoi.com#known-transports">the list of known transports for Pino</a>.</p><p>At Jolimoi we are using Winston on our legacy and we are using Pino on our new application. We made the change because we are using <a href="https://fastify.dev/?ref=tech.jolimoi.com">Fastify</a> and Fastify is using Pino. If both need to be compared, Pino is actually having better <a href="https://github.com/pinojs/pino/blob/master/docs/benchmarks.md?ref=tech.jolimoi.com">performance</a> than Winston.</p><p>What we expect from those libraries:</p><ul><li>Be able to log to standard output</li><li>Being able to write logs as JSON</li><li>Having different log levels</li><li>Sending logs to different services (NewRelics, Cloudwatch, &#x2026;) using easily configurable transports</li><li>It does not affect the performance of our application</li><li>In bonus, redaction: we want to have the possibility of anonymizing some data in the log automatically</li></ul><h3 id="example-with-pinojs">Example with Pino.js</h3><p>You can find in the documentation of Pino.js a <a href="https://getpino.io/?ref=tech.jolimoi.com#/docs/web">list of example using different frameworks</a>.</p><p>We will just give a little example here without any framework, to explain how it works.</p><p>We created a custom class to encapsulate the logger, that way we could simply switch to another library by recreating a similar class with the same methods.</p><p>First, we create a module **<code>development.ts</code>. This module exports the logger options object that allows us to configure our logger. We create this module to configure the logger when we are in development, it allows us to set a different configuration than what we need in production. Here we are using the transport<a href="https://github.com/pinojs/pino-pretty?ref=tech.jolimoi.com"> Pino-pretty</a>.</p><pre><code>import type { LoggerOptions } from &apos;pino&apos;

const formatTime = &apos;HH:MM:ss Z&apos;

const development: LoggerOptions = {
  level: &apos;debug&apos;,
  transport: {
	target: &apos;pino-pretty&apos;,
	options: {
  	translateTime: formatTime,
  	ignore: &apos;pid,hostname&apos;,
	},
  },
}

export default development
</code></pre><p>Then we create a module **<code>loggerOptions.ts</code>. That module&#x2019;s purpose is to load the correct configuration depending on the environment. By default, if no environment is set in the <strong><code>.env</code></strong>, it will use the development configuration.</p><pre><code>import type { LoggerOptions } from &apos;pino&apos;

import development from &apos;./development&apos; // (1)
import production from &apos;./production&apos;

type AvailableLoggerConfig = Record&lt;string, LoggerOptions&gt;

const availableLoggerConfig: AvailableLoggerConfig = { // (2)
  development,
  production
}

const loggerOptions: LoggerOptions = availableLoggerConfig[process.env.ENV ?? &apos;development&apos;] // (3)

export default loggerOptions
</code></pre><ol><li>First, we import the configuration</li><li>Then we create an object that will contain all the available configuration</li><li>We get the configuration depending on the environment</li></ol><p>Finally we create a module **<code>logger.ts</code>, that will export the logger instance, so we can use it everywhere.</p><pre><code>import loggerOptions from &apos;@./loggerOptions&apos; // (1) 
import type { Bindings, ChildLoggerOptions, Logger, LoggerOptions } from &apos;pino&apos;
import pino from &apos;pino&apos;

class JolimoiLogger { // (2)
  private log: Logger&lt;LoggerOptions&gt; // (3)

  constructor() {
	this.log = pino(loggerOptions) // (4)
  }

  public debug(obj: object, msg?: string, args?: any[]) {
	return this.log.debug(obj, msg, args)
  }

  public info(obj: object, msg?: string, args?: any[]) {
	return this.log.info(obj, msg, args)
  }

  public warn(obj: object, msg?: string, args?: any[]) {
	return this.log.warn(obj, msg, args)
  }

  public error(obj: unknown, msg?: string, args?: any[]) {
	return this.log.error(obj, msg, args)
  }
}

const logger = new JolimoiLogger() // (5)

export default logger // (6)
</code></pre><ol><li>Firstly, we load our configuration to provide the appropriate options for initializing our logger; this options object is loaded based on the environment.</li><li>Next, we establish a custom class responsible for managing our logger instance.</li><li>We create a private property within this class, which will receive the Pino instance.</li><li>Within the constructor, we instantiate the Pino instance using the specified options to configure the transport.</li><li>To streamline the process, we create a public method for each logger level, akin to those found in Pino, to encapsulate the invocation of the original Pino instance method.</li><li>Finally, we create a new instance and export it, ensuring a singleton pattern, which guarantees there will be only one logger instance for our entire application.</li></ol><h2 id="conclusion">Conclusion</h2><p>Logging plays a crucial role in web applications, impacting various aspects such as performance, security, monitoring, and debugging. When improperly utilized, it can result in significant costs. Therefore, it is imperative to give careful consideration to logging and choose the appropriate logging library based on your specific needs.</p><p>I would recommend using Pino or Winston which offer excellent solutions for sending logs to multiple destinations. With a wide range of available transports, these logging libraries provide flexibility and ease of use. Additionally, if none of the existing options meet your requirements, both libraries allow you to create custom transports tailored to your unique logging needs.</p><h3 id="bibliography">Bibliography</h3><ul><li><a href="https://sematext.com/blog/node-js-logging/?ref=tech.jolimoi.com">https://sematext.com/blog/node-js-logging/</a></li><li><a href="https://dev.to/amoled27/best-practices-for-logging-in-nodejs-4clk?ref=tech.jolimoi.com">https://dev.to/amoled27/best-practices-for-logging-in-nodejs-4clk</a></li><li><a href="https://developers.redhat.com/articles/2021/05/10/introduction-nodejs-reference-architecture-part-2-logging-nodejs?ref=tech.jolimoi.com#what_makes_a_good_logging_tool_">https://developers.redhat.com/articles/2021/05/10/introduction-nodejs-reference-architecture-part-2-logging-nodejs#what_makes_a_good_logging_tool_</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Our Vue guidelines]]></title><description><![CDATA[<p>Working with multiple people in a start-up project requires good communication and some conventions to accept to scale successfully and match the product need in productivity. However, because almost infinite possibilities exist to code the same feature, we need to get our stories straight and create guidelines that are easy</p>]]></description><link>https://tech.jolimoi.com/our-vue-guidelines/</link><guid isPermaLink="false">6508415d49630a03d967c045</guid><dc:creator><![CDATA[Kevin Besset]]></dc:creator><pubDate>Wed, 18 Oct 2023 08:27:18 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2023/09/mohammad-rahmani-8qEB0fTe9Vw-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://tech.jolimoi.com/content/images/2023/09/mohammad-rahmani-8qEB0fTe9Vw-unsplash.jpg" alt="Our Vue guidelines"><p>Working with multiple people in a start-up project requires good communication and some conventions to accept to scale successfully and match the product need in productivity. However, because almost infinite possibilities exist to code the same feature, we need to get our stories straight and create guidelines that are easy to follow, which benefits the team&apos;s efficiency but also helps in delivering high-quality features, easy maintenance, and good readability.</p><h2 id="our-vision">Our vision</h2><p>According to the need, we started to create the core principles that we believe will make important improvements in the quality of our deliverables. We have 3 core principles that are very close to each other and will lead our thoughts on changing/adding new good practices.</p><h3 id="component%E2%80%99s-independence">Component&#x2019;s independence</h3><p>The first principle is that we should be able to create independent components that are - in theory - easy to extract from one project to another. This is the initial goal of the component system in a front-end framework like VueJs. We want to keep this ideology and use it across our daily code.</p><p>Creating components will help in code readability and also help us to factorize and avoid having code duplicates. Because having twice the same code means that if you want to change it, you have to change it everywhere, and also, the same if you want to remove it or improve it.</p><p>Despite the fact that a more independent component can be easily extracted, it also means that we reduce the things that will impact our own components, which makes it easier to maintain. This does not mean that we don&#x2019;t create relations between our files, in fact, we do it a lot but we try to keep a simple communication, easy to understand, and easy to find between our component and external impacts like API, props inheritance, compositions, etc&#x2026;</p><p>One example that would conflict with this vision would have been if we created an entire page in a single component. Data are being fetched from one place (Store, API call), then treated from another place. Admitting we are receiving the data (helpers or libraries) and then received in our component by inheritance (mixins). Hence, everything is magic and nothing tells you in this component that you have the data you want, formatted the way you want unless to walk through the whole path.</p><h3 id="smart-dumb-components">Smart &amp; dumb components</h3><p>The second pillar is smart and dumb components which can be a little bit different from what you can read about those terms elsewhere. </p><p>In our case, our dumbest components are when it has no business logic inside, its goal is to show some data he doesn&#x2019;t even know about. Most of our UI components like buttons or modals are dumb components.</p><p>We call a component smarter when it adds strong context or business logic. Most of the time, it is built from dumber components assembled with context or specific data. For example, we can imagine a component that renders a card for a premium member with their name, and avatar, &#x2026; So it is built from an avatar and a card (dumb) component and thanks to its context, creates a member card.</p><p>Doing that means that our dumbest components need a lot of effort in the making because they need to be very adaptive and robust to be used everywhere. The smarter the component is, the easier it is to create because it is just placing some already existing component and matching it with our context.</p><p>As you can see it&#x2019;s not a two-sided concept, a component is not either dumb or smart. It is just smarter than one and dumber than another so we can think of that as a &#x201C;smart scale&#x201D;. A generic button is dumber than an &#x201C;add to cart&#x201D; shopping button, which is dumber than an order card with this button, which is dumber than a shopping cart page.</p><h3 id="black-box-design">Black box design</h3><p>The last principle wraps up the first 2. Even if dumb components might be complex to create, we still need to be easy to work with inside our application. To do that, we have commonly agreed that we don&#x2019;t need to know how the component works inside, we just want to use it so we need the communication interface contract with it to be crystal clear and self-documents the component itself. After that, all devs should be able to use it freely and have what they expect.</p><p>Of course, this concept doesn&#x2019;t work only for the dumbest components but for any components, and this is why we have a <a href="https://storybook.js.org/?ref=tech.jolimoi.com">Storybook</a> design system displaying our available components to make it much simpler to find and use the correct components. </p><p>Finally, we can imagine that if we need to work inside a dumb component which is a black box, it would be super hard to get in and we would need a front-end expert but due to the &#x201C;Component&#x2019;s independence&#x201D; and &#x201C;Smart &amp; dumb design&#x201D;, we believe it&#x2019;s not that complicate to work inside and make improvements and we also added some extra guidelines to ease it a little more.</p><h2 id="matching-vue-trends-with-our-vision">Matching Vue trends with our vision</h2><p>In order to help the readability of our code, we have chosen to follow the Vue trends proposed by its community and adapted to the previous principles.</p><h3 id="strict-vue-eslint-rules">Strict Vue ESLint rules</h3><p>At Jolimoi, we have decided to have a very strict technical environment and guidelines and we chose ESLint to handle most of the job for us. This way, most of the code is produced with the same conventions so we are more efficient in reading and understanding the code already in place.</p><p>So we decided to use <a href="https://eslint.vuejs.org/?ref=tech.jolimoi.com">Vue ESLint rules</a> from their documentation and apply all the rules possible inside our code base. We applied all base, essential, strongly recommended, recommended, and uncategorized rules to our linter. Some of them were incompatible with our way of coding so we chose to disable them for now and we also configured some of the rules with the recommended settings most of the time. We are in the middle of a rewriting migration so we are adding these rules little by little in our codebase, but this is the goal we are aiming for.</p><p>Once it&#x2019;s in place, and of course it breaks our CD/CI if we have any errors during the linting, all developers use it and agree with the code guidelines. For example, Vue gives us rules to forbid the creation of components of one word only. Every component must be at least 2 words combined in order to differentiate between HTML tags and Vue components, so it&#x2019;s easier to see/read. We also have rules to disallow us to create anti-patterns like mutating props, or to forbid having a v-if at the same level as a v-for.</p><h3 id="composition-api-over-option-api">Composition API over Option API</h3><p>Also, Vue appeals to us to use more composition API, especially with the script setup syntactic sugar. We wanted to use composition API because it adds much more possibilities to manipulate our code outside/across our Vue components which gets very important when you want to factorize your code and avoid duplicates.</p><p>Also, we believe that using composition is a good option to handle impacts coming from outside a component since it&#x2019;s clear enough to understand where it comes from (and easy to navigate through it with a code editor) . Also, using composable for example, we can &#x201C;scope&#x201D; our impact and also get only the minimum required for our component to work properly, which is super compatible with our vision.</p><p>So we have decided to switch to composition API and script setup. In fact, it&#x2019;s a simple conversion that even ChatGPT can do for us. On top of that, we have chosen a few guidelines to ease the skill improvement such as choosing ref() over reactive(). Ref() may be trickier than reactive() but works in all scenario and we believe that it helps us to understand better how Vue work. Also, we have decided to organize the most efficient way our code and group them: declarative variables (such as props, composable, emit), const/data, computed, methods, lifecycle methods, etc. so it&#x2019;s easier to read and find what&#x2019;s affecting what inside our component.</p><p>Also, since we are not in an object anymore, it feels obvious that having a huge component with a lot of code and complexity inside is getting very hard to read and maintain so we are more encouraged to extract code outside, especially with the full power of composition API.</p><p>For example, we have a feature flagging library that we want it to disable, regarding a tag which is a boolean get from Firebase, a specific part of our codebase. Previously we had a mixin given to every component in our application that initialized our firebase got all of the feature flags and then populate asynchronously some methods and data. It works well but we have a few problems:</p><ul><li>since it&#x2019;s asynchronous, it&#x2019;s difficult to evaluate whether the data is passed or not</li><li>by looking at our component, it is impossible to know that we have these properties inside which makes it hard for newcomers to start working on the stack</li><li>it&#x2019;s impossible to use these feature flag checks outside a Vue component as it is today</li><li>since we now want to use script setup, mixins are no longer compatible</li></ul><p>So a better way to handle this would be to rewrite the mixin into a composable with something like const { isFeatureEnabled } = useFeatureFlag() so now, inside a component if we want to use it we import it so we know where it comes from and if we want to use it outside the component, we can.</p><h3 id="minimize-store-usage">Minimize store usage</h3><p>We believe that using a global store like Vuex or Pinia is a core-breaking principle since it creates impact across all our components while nowadays, we can do almost everything we commonly do inside a Vue store with composition API to communicate across multiple components inside our application.</p><p>Most developers use Vue store in order to either store data we want to use across the entire application or store data in order to cache it. For the 2 needs, we have an answer: we use composition API and composable so we can use data across the app. For caching, the only thing we&#x2019;d like to cache right now is API calls, and for that, Tanstack/query does the job for us perfectly.</p><p>For example, we like to use Vue store for authentication across the application and to have the user everywhere but with composition API, we can handle it super easily without any other libraries. We created a useAuth() composable that handles everything for us, which is Vue-reactive and can be easy either inside any components and also outside. Of course, it handles both sides: get the currently logged-in user but also some actions such as login or logout.</p><h2 id="conclusion">Conclusion</h2><p>To conclude, all the guidelines you just read are a vision, it&#x2019;s more of a goal to reach but it can happen that sometimes, for various reasons, we do &#x201C;bad code&#x201D; that doesn&#x2019;t follow every guideline here. We want to involve developers to think of what they create and especially why they create it this way. Doing this helps us to decrease the chances of having struggles to maintain some code later.</p><p>We just believe that keeping our mind on this will help the product and the dev team to improve and it will ease our daily tasks.</p>]]></content:encoded></item><item><title><![CDATA[Enhancing UX through Query and Dashboard Management on Metabase]]></title><description><![CDATA[<p>At Jolimoi, the data assets play an important role in productivity, efficiency and visibility, that&apos;s why we decided to do a cleaning of the data visualization tool (Metabase). We divided the project into distinct phases due to the amount of assets in our &#xA0;organization. Transforming from a</p>]]></description><link>https://tech.jolimoi.com/enhancing-ux-through-query-and-dashboard-management-on-metabase/</link><guid isPermaLink="false">64f5ef4249630a03d967bfa3</guid><dc:creator><![CDATA[Brenda Rivera]]></dc:creator><pubDate>Wed, 20 Sep 2023 08:00:24 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDh8fGJvb2tzfGVufDB8fHx8MTY5MzgzOTIxNnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDh8fGJvb2tzfGVufDB8fHx8MTY5MzgzOTIxNnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Enhancing UX through Query and Dashboard Management on Metabase"><p>At Jolimoi, the data assets play an important role in productivity, efficiency and visibility, that&apos;s why we decided to do a cleaning of the data visualization tool (Metabase). We divided the project into distinct phases due to the amount of assets in our &#xA0;organization. Transforming from a noticeable disorder to a better structured tool which will positively &#xA0;impact the company.</p><p>Our data visualization tool is a self-service business intelligence oriented that helps our teams to perform: </p><ul><li>Data exploration</li><li>Create dashboards</li><li>Generate alerts when data does not follow specific business defined rules</li></ul><p>All of this will help stakeholders to speed-up and ease their decision-making and made everything much more transparent for the collaborators.</p><p>In this blog post, I will share the process and the lessons learned from the data team in this project.</p><h2 id="phase-1interviews">Phase 1 - Interviews</h2><p>This phase aims at understanding the importance of feedback from different teams using Metabase.</p><p>During the Interview Process, we interviewed our teams to understand how they interact with Metabase to identify pain points and inefficiencies in the current process.</p><h3 id="interview-methodology">Interview methodology</h3><p>We selected key users from each team to participate in recorded &#xA0;interviews. The goal was collecting insights and prioritizing future improvements.</p><h3 id="questions">Questions</h3><p>Choosing the right questions was important for the interview process, we wanted to understand users roles &#xA0;and how they interact with Metabase and the data in general. We defined 3 stages of questions:</p><ul><li><em>Own interaction</em> stage where we want to understand how they process to get data in general terms we asked questions like: do you currently analyze any data? which? and how? How often? Do you have any periodicity usage on a daily, weekly, monthly basis?</li><li><em>Metabase interaction</em> stage where we ask about data visualization tools and how deep they know Metabase we asked questions like: Have you used any visualization tool before? Are you currently using Metabase? Do you know what metabase is?</li><li><em>Role experience in</em> Metabase stage to know how they incorporate it into their regular tasks and we asked questions like: Do you have some links or question IDs pinned or favorite to use questions saved that can be accessed easily? Is it easy for you to find the requests on Metabase by using the search bar?</li></ul><h3 id="data-collection">Data collection</h3><p>After conducting interviews, it was essential to prioritize improvements based on the data collected. This process aimed to address identified issues and concerns. By considering the feedback received during the interviews, we determined which improvements were most important and should be prioritized.</p><p>In this level we found some common issues like:</p><ul><li>&#x1F449; <em>Most of the users didn&apos;t &#xA0;feel comfortable using metadata due to the amount of keywords and names found</em></li><li>&#x1F449; <em>Users copy data in Google Sheets for their own analysis (high usage of raw data)</em></li><li>&#x1F449; <em>Users are willing &#xA0;to get more experienced in Metabase</em></li><li>&#x1F449; <em>The most required improvement was to arrange all the questions and tags to &#xA0;facilitate the search experience</em></li><li>&#x1F449; <em>Users regularly use data from Metabase on a daily basis</em></li><li>&#x1F449; <em>Some users knew how to use filters or summarize functions. This users use this features to search and refine data presented by Metabase </em></li><li>&#x1F449; <em>Some users bookmarked their frequently used questions in the browser </em></li></ul><h2 id="phase-2cleaning-metabase-old-assets">Phase 2 - Cleaning Metabase old assets</h2><p>As part of immediate actions we decided to go with bulk archiving questions based on different particularities scheduled for every quarter creating dashboards to track the cleaning process.</p><p>First we needed to identify assets that were not used for a long period of time and create confusion to users.</p><h3 id="cleaning-assets-rules">Cleaning assets rules</h3><p>Data team must ensure this process is followed correctly and provide help to any other user when facing a problem for a missing request.</p><ul><li><em>&#x1F449; Request with no views for the past 6 months or a maximum of 10 views, including all admin users requests that satisfy the conditions</em></li><li><em>&#x1F449; Request that had been archived for more than 6 months</em></li><li><em>&#x1F449; Every admin user will be in charge of cleaning his/her own assets periodically</em></li><li><em>&#x1F449; Rules will not affect personal collections of any user</em></li><li><em>&#x1F449; Requests created by new Data Team members or that are in Technical collection on Metabase will be excluded from automatic archival (this collection is used to stored some technical assets like Metabase models)</em></li><li><em>&#x1F449; We encouraged users to archive unused requests or move regularly used requests from their personal collections to a common collection</em></li><li><em>&#x1F449; Unused requests from users&#x2019; personal collection can be archived by the data team if it deems these requests not useful, without informing the user</em></li><li><em>&#x1F449; Metabase naming convention should be followed by all users for the requests that are moved to common collections</em></li><li><em>&#x1F449; Data Team is free to modify the request names according to the naming convention for the requests that will be moved from personal to common collections</em></li><li><em>&#x1F449; There are some assets that are only reviewed once a year, for these we have a special list to exclude them from archiving</em></li></ul><h3 id="bulk-cleaning">Bulk cleaning</h3><p>With the amount of different assets needed to be reduced, we test the cleaning process on a smaller scale before executing it in bulk.</p><p>When we do this process some points come up, we need to be careful in all the requests that appear in different scenarios, like requests that are consulted once a year or personal collections, admin requests that are a work in progress, we ensure the bulk cleaning did not affect the current operations of all the users.</p><h3 id="documentation-updated">Documentation updated</h3><p>We create some referential documents regarding the process and rules to give the users a better understanding of the origins of the project and how we manage bulk erasing requests to maintain visibility to users.</p><h3 id="follow-up">Follow Up</h3><p>We scheduled some slack alerts for this process to ensure the process is followed correctly and simultaneously. </p><p>We also organized Metabase training for basic and intermediate level to ensure the tool is well used and the rules well interpreted.</p><h2 id="conclusions">Conclusions</h2><p>In conclusion, keep our Metabase clean is important for improving the user experience. </p><p>By regularly cleaning out these &quot;old&quot; assets, we can ensure that users are provided with accurate and up-to-date information, a cleaner interface simplifies the user journey, without being overwhelmed by unnecessary content and increase trust in the tool&apos;s reliability.</p><h3 id="how-we-measure-success">How we measure success?</h3><p>At performance level, we create a &quot;cleaning&quot; monitoring dashboard. We used it to quickly track some KPIs regarding assets cleaned. </p><p>This displays key metrics, including the overall volume of archived requests as well as those archived within the last six months. This will provide us with valuable insights into the performance and effectiveness of the archiving process.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/09/image-2.png" class="kg-image" alt="Enhancing UX through Query and Dashboard Management on Metabase" loading="lazy" width="1517" height="353" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/09/image-2.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2023/09/image-2.png 1000w, https://tech.jolimoi.com/content/images/2023/09/image-2.png 1517w" sizes="(min-width: 720px) 720px"></figure><p>Simultaneously, we are enhancing the monitoring of active requests by implementing visualizations that help to identify requests that are receiving no views, allowing us to queue them for archiving once they meet the threshold.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/09/image-3.png" class="kg-image" alt="Enhancing UX through Query and Dashboard Management on Metabase" loading="lazy" width="1600" height="709" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/09/image-3.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2023/09/image-3.png 1000w, https://tech.jolimoi.com/content/images/2023/09/image-3.png 1600w" sizes="(min-width: 720px) 720px"></figure>]]></content:encoded></item><item><title><![CDATA[Teleport in Vue 3]]></title><description><![CDATA[What is Teleport in Vue 3 and how to use it .]]></description><link>https://tech.jolimoi.com/teleport-in-vue-3/</link><guid isPermaLink="false">647dad7849630a03d967bbad</guid><dc:creator><![CDATA[Corentin Lissillour]]></dc:creator><pubDate>Wed, 06 Sep 2023 07:33:02 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2023/06/New-Project--10-.png" medium="image"/><content:encoded><![CDATA[<h2 id="what-is-teleport">What is Teleport? </h2><h3 id="principe-of-teleport">Principe of Teleport</h3><img src="https://tech.jolimoi.com/content/images/2023/06/New-Project--10-.png" alt="Teleport in Vue 3"><p>Teleport is a component that appeared in Vue 3. </p><p>This component allows displaying its content to slot elsewhere in the DOM. To do that the component has props &#x201C;<em>to</em>&#x201D;. This prop uses a CSS selector to know where to display the content of the Teleport.</p><p>With Teleport, it&#x2019;s possible to interact on the DOM external of your component scope while using an ordinary component easily manipulated. </p><p>Teleport has another prop &#x201C;<em>disabled</em>&#x201D;. This prop allows disabling the teleport of the content and adding the content to the DOM normally.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABZkAAANJCAYAAABu3TJKAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3Xl8XHW9//H3mcmeNumWNm3TNum+AYWWUnbcNxQUxKs/VC4oKoKiXlwvigoqIoiKK4u4X3EBBS9XRdn3lrV0b5MmbZo2bdMt+2TO7/E5YdppMlnmzCSz5PV9PHyombN8v8/vOf3jPd/5fB3REEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDwKeD4PI/TEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAQITMPAQIIIIAAAggggAACCCCAAAIIIIAAAggggIBvAUJm33SciAACCCCAAAIIIIAAAggggAACCCCAAAIIIEDIzDOAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4FuAkNk3HScigAACCCCAAAIIIIAAAggggAACCCCAAAIIEDLzDCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgj4FiBk9k3HiQgggAACCCCAAAIIIIAAAggggAACCCCAAAKEzDwDCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAr4FCJl903EiAggggAACCCCAAAIIIIAAAggggAACCCCAACEzzwACCCCAAAIIIIAAAggggAACCCCAAAIIIICAbwFCZt90nIgAAggggAACCCCAAAIIIIAAAggggAACCCBAyMwzgAACCCCAAAIIIIAAAggggAACCCCAAAIIIOBbgJDZNx0nIoAAAggggAACCCCAAAIIIIAAAggggAACCBAy8wwggAACCCCAAAIIIIAAAggggAACCCCAAAII+BYgZPZNx4kIIIAAAggggAACCCCAAAIIIIAAAggggAAChMw8AwgggAACCCCAAAIIIIAAAggggAACCCCAAAK+BQiZfdNxIgIIIIAAAggggAACCCCAAAIIIIAAAggggAAhM88AAggggAACCCCAAAIIIIAAAggggAACCCCAgG8BQmbfdJyIAAIIIIAAAggggAACCCCAAAIIIIAAAgggQMjMM4AAAggggAACCCCAAAIIIIAAAggggAACCCDgW4CQ2TcdJyKAAAIIIIAAAggggAACCCCAAAIIIIAAAggQMvMMIIAAAggggAACCCCAAAIIIIAAAggggAACCPgWIGT2TceJCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAoTMPAMIIIAAAggggAACCCCAAAIIIIAAAggggAACvgUImX3TcSICCCCAAAIIIIAAAggggAACCCCAAAIIIIAAITPPAAIIIIAAAggggAACCCCAAAIIIIAAAggggIBvAUJm33SciAACCCCAAAIIIIAAAggggAACCCCAAAIIIEDIzDOAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4FuAkNk3HScigAACCCCAAAIIIIAAAggggAACCCCAAAIIEDLzDCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgj4FiBk9k3HiQgggAACCCCAAAIIIIAAAggggAACCCCAAAKEzDwDCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAr4FCJl903EiAggggAACCCCAAAIIIIAAAggggAACCCCAACEzzwACCCCAAAIIIIAAAggggAACCCCAAAIIIICAbwFCZt90nIgAAggggAACCCCAAAIIIIAAAggggAACCCBAyMwzgAACCCCAAAIIIIAAAggggAACCCCAAAIIIOBbgJDZNx0nIoAAAggggAACCCCAAAIIIIAAAggggAACCBAy8wwggAACCCCAAAIIIIAAAggggAACCCCAAAII+BYgZPZNx4kIIIAAAggggAACCCCAAAIIIIAAAggggAAChMw8AwgggAACCCCAAAIIIIAAAggggAACCCCAAAK+BQiZfdNxIgIIIIAAAggggAACCCCAAAIIIIAAAggggAAhM88AAggggAACCCCAAAIIIIAAAggggAACCCCAgG8BQmbfdJyIAAIIIIAAAggggAACCCCAAAIIIIAAAgggQMjMM4AAAggggAACCCCAAAIIIIAAAggggAACCCDgW4CQ2TcdJyKAAAIIIIAAAggggAACCCCAAAIIIIAAAggQMvMMIIAAAggggAACCCCAAAIIIIAAAggggAACCPgWIGT2TceJCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAoTMPAMIIIAAAggggAACCCCAAAIIIIAAAggggAACvgUImX3TcSICCCCAAAIIIIAAAggggAACCCCAAAIIIIAAITPPAAIIIIAAAggggAACCCCAAAIIIIAAAggggIBvAUJm33SciAACCCCAAAIIIIAAAggggAACCCCAAAIIIEDIzDOAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4FuA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REAEREAEREAEREAEagYBicw1I4+ahQjUWAI1SWSusUkC0Prwseg49nIzxbm3nImcrFU1ebqamwiIgAiIgAiIgAiIgAiIgAiIgAiIgIOARGbdDiIgAnFNQCJzXKendHAD7n3dVGbv/Gsxfr7nwuoxaI1SBERABERABERABERABERABERABEQgJgQkMscEozoRARGoLAISmSuLbOz6bdR3OA64/H7T4dJXJiLr+6mx61w9iYAIiIAIiIAIiIAIiIAIiIAIiIAIxD0BicxxnyINUARqNwGJzPGZ/9QmLWG5E1C3fTd0PPVyJNbJRP72LZhzwynwFBXG56A1KhEQAREQAREQAREQAREQAREQAREQgUohIJG5UrCqUxEQgVgRkMgcK5Kx7WfEi9NhuVylnXo9xVj0xHhkL5od2wupNxEQAREQAREQAREQAREQAREQAREQgbgnIJE57lOkAYpA7SYgkTk+82+LzMV5Odi5YjFWTn4ZO/5YGJ+D1ahEQAREQAREQAREQAREQAREQAREQAQqlYBE5krFq85FQAQqSkAic0UJ6nwREAEREAEREAEREAEREAEREAEREAERqFwCEpkrl696FwERqCABicwVBKjTRUAEREAEREAEREAEREAEREAEREAERKCSCUhkrmTA6l4ERKBiBCQyV4yfzhYBERABERABERABERABERABERABERCByiYgkbmyCat/ERCBChGQyFwhfDpZBERABERABERABERABERABERABERABCqdgETmSkesC4iACFSEgETmitDTuSIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQ+QQkMlc+Y11BBESgAgQkMlcAnk4VAREQAREQAREQAREQAREQAREQAREQgSogIJG5CiDrEiIgAtETkMgcPTudKQIiIAIiIAIiIAIiIAIiIAIiIAIiIAJVQUAic1VQ1jVEQASiJiCROWp0OlEEREAEREAEREAEREAEREAEREAEREAEqoSAROYqwayLiIAIREtAInO05HSeCIiACIiACIiACIiACIiACIiACIiACFQNAYnMVcNZVxEBEYiSgETmKMHpNBEQAREQAREQAREQAREQAREQAREQARGoIgISmasItC4jAiIQHQGJzNFxq+hZ7U+4AG2PPtt08925w0N21/PaR9DggIHwFBbg+0sPh7e4KOQ58digbde6uPTB3rAs4Is3VuLrd1bHZJidetfHBff0MH09f/NCLF+0PSb9VkUn7qQUFBfkVcWlasU1LJcbvMGq62ekViRJkxQBERABERABERABERABEYiYgETmiJHpBBEQgaokIJG5Kmn/fa1IReY+N01CZiefiPq/i0YZsbk6hlMM/u79NZj2779iMo2qFJm7nnczmg07EtuXzsf8iVeY8Tc/6Gh0OedGeD0eTD9/RFhzSm3cAq0OPQX19++PubecGdY5ahScQEJqOlqMHIOW/zgJ8ydeidxNayPCFau8RnRRNRYBERABERABERABERABERCBMAlIZA4TlJqJgAjsGwISmfcN94hF5vFPI7NzL5/IfOEh8BQV7puBV/Cq+/Wshwvv62l6+fa9NfjstdorMtuiZv62zfjhuhMqSFanU/gnU8ac8adJZNYtIQIiIAIiIAIiIAIiIAIiUKMISGSuUenUZESg5hGQyLxvchqpyJzWrA2S6jU0Fcw7l/+2bwYdg6smJLnQpnMGLMvCprU52LUtNhXZ1bGSWSJzDG4oRxcSmWPLU72JgAiIgAiIgAiIgAiIgAjEFwGJzPGVD41GBETAj4BE5n1zS0QqMu+bUVafq0pkrj65qqyRSmSuLLLqVwREQAREQAREQAREQAREIB4ISGSOhyxoDCIgAkEJSGTeNzeHRObYcpfIHFue1bE3iczVMWsaswiIgAiIgAiIgAiIgAiIQLgEJDKHS0rtREAE9gkBiczRY09v2R4tRozBjuWLsGnO12U6ymjXFa2POBX1uvRBQnoG8rM3YtPcb7B66utoc/RZaHv02eac784dHnAQA+55DbyGf4Ta+C+jfTf0u+0Fc9rSfz+IrOlTgk4yIa0Ohj0xBZY7AWu/ehd/vv1U9ECCnNljWCOcNb57maORbvyXUT8JB5/cGt0HNETdhknI2VWEZb9sw1dvrUKjFqm44B7fxojP37wQyxdtj/k87A6j3SCux9UPomHPIWGPK+v7qVj6ysSy7S0X6nXpjYa9hhif7tQmLcFN74pydiNv60Zs+3UO1n39IfK3byn3WvY8tvwyA78+dRNcCYlmA8NmB45GatNWgNeL/OxN2Lb4J6z65FUU7tkZYCyWOaf5QccgvXlbs/Hh7jV/Yu0X72DL/Bk44MoH0Kj3gdgw8zMseen+oOPJaNsZLUYeh3rd+iC5XmN4PcXI3ZyFrQtmYe2X76Bw944y57Y+4jR0POXSsHnmblqHOeNPDdo+mrzW79YXTQYfhqzvJmPnX4vDHosaioAIiIAIiIAIiIAIiIAIiECkBCQyR0pM7UVABKqUgETmyHC7EpPQuP9ItBg5BpmdfBvYLXvtEaz/7uO9Omo+4hh0PmscLJerzAV2rVyK7Ut/QevDfYJXrEVm9jlo4jtIbdwC2377EQseuTboJJ3Vnz/fd3Gl+D3HQmRutV8dXHBPT6TWSSgzl5xdhfjyzVU47uL9zLGaLjK3G3Mu2o35V7k3bnF+LhY/f7cReoOFLaru+GMhFj46Dj2umoB6XfsGbB7o3rBcbux/6T1o1DfwIskfbz6OZsOOABdbgorMlgv7nXoZWv3jZMCyAl6bAvOiJ8Zj5/Jf9zoeDyJzw15D0eMq30LA7tV/YP13k7Fx9lcozsuJ7MGi1iIgAiIgAiIgAiIgAiIgAiIQgoBEZt0iIiACcU1AInN46eHGe81HHItmBx6JxPS6pSdRAPv9+buMmGtH3Q7d0eeWZ2FZLlP9ySrQnSsWg1XDrPps3G8EKAK6k1PNKcFEZp9A7RPe2h59Ftodd57551CVzGzT4aSL0OaoM01F6KyrxwSsBGU7u7qWFbCzbzjZVK/GOqgdWq6/BcT7PzwQLpeFcCuZU9LcGPfsANRtkASPx4uZU9bjt9lbzFC7DWiAg45rhaJCD5JS3GbolS0yU9xscMAgU7G7/J2nzTUb9BhsFg283mIsfOS6sBBGu/EfrVaY2+1Lfkb2ojnYs3YFCnN2ISmjHtJatEOrf5yE5AZN4CkqxE93nY8961YEHI99/ZysVaZaueUhJyBnw2psnjcd+Vs3wJWcgsz9eqBRnwPxy4TLyyxAOC1fuHCy5ou3kbc5C6lNWqHN6DNNhbW3uAjulLSgInOnM65Gy1EnmvHtWrkE67+djJyNa5CQkoa6+x2AVoeeAndyirl/591+TrnV2RW1y4gmr3XadDIic3L9xqWM+dmm0Lz+24+N8KwQAREQAREQAREQAREQAREQgVgQkMgcC4rqQwREoNIISGQOjpb2AY36HWQsMep17VPakJYA236bi6zvP8XW+TONmOeM3jc8adrz7z/fc6ERI53R5V83ovnwo0v/FExkdp7T9ph/ov3x55s/hSMyU/zqf+fLpj0tF2i94B+0WBj6xBRjk7Dm87ex/N1JlXafOTueMHl4RCLzoae1xaGntzVdfDjpD8z+LGuvcfY9uAlOvbZr6d+cInNqaiomf7J3lXm4k3zyiScxdeqn4TaPuF20IjOtMrgokLdlbw72AGh1MeDuf4NV9+XZVNjXLy7IM/fA2q/ex4r3JhnLC2dwgYVtaJ1hR1JmQwx+6D1z3q5Vy/DL/ZfAU1hQepwLKv3vegUpDZuZvwUaR73OvdB7vE+kX/fNR/jjzcfKLHJwLv1uf9HYgaz97/v4860ngnKuqMgccQLtEywXGhww0CwgsbKZTOzY9ddirP/uE2ya+18U5+dFfQmdKAIiIAIiIAIiIAIiIAIiIAISmXUPiIAIxDUBicxl08NKTNpdND/wKCRm1CttQE/XDTOmGcEsf9vmgHllReOQhz8wr/4HE/iS6tbHkEc/Au0GGJUhMrPfgfe/CQqE2b/OxcJHy1bXNht6BLqef4sZw093nw9Wo1ZFRCoy3/D8AOO5nL0hDxMvnBuw2Pqap/qhebt0M/yaLjKHk6MDLr/f2FhQiJ59wykBT7FFZh7cvmwB5k+8IuxK9taHj0XHsZebfhc+Ns5UVPsHK5RZqcwI9FnoceUENOw9zIxx7s1nlFmssfvb77Qr0erQk1GwM9tU5QeLfSYyOwaUWCcTTYccjubDRyO9VYfSI0W5e7Dxhy+NrQ4rzxUiIAIiIAIiIAIiIAIiIAIiECkBicyRElN7ERCBKiUgkbkEt2UZGwt6Ldfv1q/UH5YVnFvmTUfWjE+xfen8kCIc/ZrpU8v47Zlbsfmn6QHz2eemScjs5NuorrJE5vbHn4e2x5zjs8y46tgyG7fxNX9WXobaEC3WN2QkInN63UTc8aZvs7yZU9Zh8gvLAw7n8LPaYdQpbcwxp8jsdrsxatSoqKbw++LfsXbN2qjODeekaCuZg/XttFfpcPIloBDM6mJWvgcKp8jMjf+4AWC4ccAVDxgbDVbnzrjsCHOP+Qc9wekNzvAXmVnte+DTn8GVlIy1X72HP99+Muilmwz6B7pfdIc5/sN1JwRd4IkHkdk5CW7ASbGZ42clth30lmZ1My01aCeiEAEREAEREAEREAEREAEREIFwCEhkDoeS2oiACOwzAhKZfejpjzz82S9L88DX3GmHsWnOf8EqxHCD3sntT7jQNP/x1rOwZ/3KgKd2OedG83o9o7JE5vSW7THgntfMNZa8/ICpwrbDaZWxaurr+OvDF8KdYoXbRSIyt+1WF5c92Ntc86Nn/8QP09YHvH6fkU1w2nU+y4zK9mSuMICSDioiMvN+9dkzDEN6q/ZgBa1dGe8/vu/OOyjg4ohTZJ5x+ZEoytkd9tQG3v8W0pq1Np7D8+48N/B5loWDnv/a2Ef4i8x1Wu9n7DQiDV4rmM9xvInM9twopHMBixY5tDqxNzice8uZoB+2QgREQAREQAREQAREQAREQATCISCRORxKaiMCIrDPCEhk9qF3isysymQFMkXZ7F9/BLx7e9SWlyxWkLY58nTTZNY1x6Fgx9aAzTuecim40RijskRm9k2RmWJz9qLZWPjY9aVjaTr0cHQ7/1bz79xQbffawBXClXFjRiIyd+3XAOfeeYAZxlsPLcH8//3tC+wcW9f+DXDuHb52NV1kDrTZXHl5mn7+iDI+y2xf6smcl4PvLz08olQPffwT0PZl2+KfseChq4KeO+yJKcZyxl9krt+9H3qNezyia7Lxz/ddXGYDQruTeBWZOb7Mzr18Vc0DDjHV2wyJzBGnXyeIgAiIgAiIgAiIgAiIQK0mIJG5VqdfkxeB+CcgkbkkR5YLLUcdbzb5oyhrB72XN8z8HBtmTkPuxtDWCfEmMtMug7YZfC1/5lXHlFar2n64rKSk2FWVUZUiM+0yjjzyiKimt2jRIqxatTqqc8M5KZpKZi6GDHzgLSTXawRPQT5Wf/42tsz7zlie0NrFDlbTs6qeMf38kQHtLOzrh/I6DjSXUpH595+w4GGf73J57coTmRe/cLexjqhoxJvITH/2ZsOOQLMDjwJ93u3I3bweWdOnYO1/3zM5VIiACIiACIiACIiACIiACIhAOAQkModDSW1EQAT2GQGJzGXR0yuZYnPjAQfDlZhU2mDHsgXImjENm3/8FsX5uQFz1uaoM9HhpIvMsX1tl8Ex0NKA1gaMJS/dbypKnVYZKye/gpWTX67S+y8SkblNl7q4/OHo7TJSU1Mx+ZOPo5rfk088ialTP43q3HBOikZkpuVCl3/daLpf9MSN2LpgVsBLdT7rOrQ4+DhzrDJE5grbZbTphP53+u675e88jTVf+LybKxLxIDLTGqRRn+FoNnw06u/fH5blMlPi2xFb58/E+m8nI/t3vh3hrchUda4IiIAIiIAIiIAIiIAIiEAtJCCRuRYmXVMWgepEQCJz8GwlptdF02FHoMWIY5HWvG1pQwrMFJopOFN4dga9V/e/7F7zp1hu/NfmqDPQ4aSLTb/caC0Sn2iKebRY2LrwByx6/AY0HXIYul1wm+mrZvb3eAAAIABJREFUPCG8su7j+z84EAlJLnw/eR2mvFi+TUdaRgLufGuoGUo0G//VNJG505nXouUhx6Nozy7MuOKooCnqc/OzyNzPZx8y/YKDA24wV5FK5gOufACNepe/8V9Ko+YY/OC7ZgwBN/6b9IXxa6Y1DT8rFY19KTJntO1shOWmgw5FQnpG6VTytm5A1v+mmv8Fs86p6Lx1vgiIgAiIgAiIgAiIgAiIQO0gIJG5duRZsxSBaktAInN4qeOGXS1GjkGjfiOMMGZH7qa1WPLyhFKxOSmzIYY8+qGpYKSnMzfc84+kug18bVxucygcT2Zu8sbNAhmRerna1dWeokLMuuoYdL3gViMQ7lm7Aj/e/s/wAMSw1S2vDkJmw2Qs+H4z3nxwcciex03qjyat07A1KxcPXvRjwCLQa5/qh2bt0k1f1cWT2a425oZ73HgvnGAVM6uZi/Pz8P2lhwWsiE1r1gYD73ujdIM5+i0X5+WU6b4iInPrw09Fx7GXmT4XPjYO2YvmlOmfYjhFcYa/yMy/9bzmYTToMQi8L+fefDrytmwIB0HQNvQ77n7JXeb4vDv+hd1r/qxQf+GcTGudbhfegTqtO5Y293o8yF74A9Z/NxlbySUCT/dwrqk2IiACIiACIiACIiACIiACtZOARObamXfNWgSqDQGJzJGlKrFOpvFYbTHy2FKf1WWvPYL13/1tydDzukfQYP+BRjz7+e4LymyqZ4t79pXDEZlZKdnvjpfMKSvefx6rp70R9sCdFaV/vPEYOp56uRHK//rw/7Bq6mth9xOrhufctj+6D2yI3N1FuPec2SjML39jxYNPbo0jz/b5ZH/4zB+Y/XnWXkPpN6opxl7dpfRv1UVkdlqrzBl/GrhgESros0y/ZQar0lmd7gx3cgp6jXsMdTv6qpgZP4w7EfnZZTdMrIjITE/oQQ++a+6j3av/MBvyeQoLSq9JS5b+d70C3nuMQCJz/W590ev6J8zxXX8txoJHrzMV2oGiQY/Bxvpl7VfvBUVUt+P+6HvLc+b40lcnmurhyo6GvYaix1UTzWXo3+6rWp5i/lkhAiIgAiIgAiIgAiIgAiIgArEkIJE5ljTVlwiIQMwJSGSOEqllgSJZi5HHIXvRbGR9/7d3LwXhvrf9HyyXC4W7thvP450rFpvX6Gm90bj/SFNZ6k5JMxcPR2RmuwH3vGY2JaSYR6F5x7L58BQVmT74Kn7h7h1BJ9PvtheQ0b6bsdmgAMiYc9NpYW1mGCWhoKf1PLAxzryxmzm+fOF2fPPeGuza5hMoPR4vNq3Zu+o2KcWN65/tj8xGyfAUezH9o7X4fc5WwIIRqw86rhWKCj1ITvVVhlcXkZn5YF4Yu1YuwYr3n8OedSvhKfRtBsdFCv+N4VIbt8CA+94w4i5zufrT100VPe+JOu26oPXhpxkxlmKtbdvw832XYOfyX8vkoyIiMztzbi7I/ldNec1sQJjatBXaHXeeGQfLznmfBxKZ2UenM65Gy1EnmrHlb9+CdV+9hx3Lf4MnPxeJdRsYy48mA0eZPoP1YU+MTIY+NtnMu2DnNiz/z9PY8eciFOX4hGtWGAeq6K7I/U3xu9U/TvRVLS+YZa6hEAEREAEREAEREAEREAEREIHKICCRuTKoqk8REIGYEZDIHDOUe3XUfPhodP7nDUZo9g8KivR07nDyJeZQuCIzBbde4x6HKym5TJ9/vv0U1n7l878NFE57Ax7ftWoZfrrrvMqZfBi9/vOW/bH/4IZlWubtKcLtp5bdzK5lhzq44N6eoEezf+TsKsSHk/4sFa6ri8jMedDegTYPgSLr+6lY+oqvStYZtMvofM71pZvK+R9nFe3vz92BPjdNMoeW/vtBZE2fUqafiorMtHuh/3ijPgeWHb7Xa67bbsy5SK7fOLhAbLnQ8eSL0erwsUHnY3e+9r/v48+3fJXPwYKbHdKGJFBQAJ8z/tQw7k41EQEREAEREAEREAEREAEREIH4IyCROf5yohGJgAg4CEhkrrzboW77bmh91BnI7NQDCWkZyM/eiE1zvsaqT19Hwx6DSzcIDFdk5khZJd3u+PORuR/7rFM6+FAic3KDJhjy0PulPr2sml097c3Km3yInt0JFkae2Bp9D26KBk1TwH9nBBOZeaxugyQcckobdBvQAHUbJGPPzkIs+2UbvnprFfJzi0o3CKxOIjMXIVoccjyaDvoH0lq0RwKr2y0fi2Ais2HR8QC0OfI0ZHbqiYQ6dY1AS59mVtXTEqVgZzYGTXwHrHzeOPsrLH7h7jIZqajIbDq0LLQ46BjQM5zj93qKjX3Gms/eMlYerCxOymyAdd98aMYVLNJbdjAWNPW69gXvVXdyKopydyMna7Wp1N7yy/fYufy3sO7Xhj2HGKYZ7boikWxKvM8lMoeFT41EQAREQAREQAREQAREQATilIBE5jhNjIYlAiLgIyCRWXeCCIhApRCwXDjoua/gSkzCyo9fwspPXq2Uy6hTERABERABERABERABERABEagNBCQy14Ysa44iUI0JSGSuxsnT0EUgjgnUadUR/e/2CcuLnrjReBYrREAEREAEREAEREAEREAEREAEoiMgkTk6bjpLBESgighIZK4i0LqMCNQwAtxA0uv1Bt1Mz7bj4CaEs647vswmhjUMh6YjAiIgAiIgAiIgAiIgAiIgApVKQCJzpeJV5yIgAhUlIJG5ogR1vgjUTgJ1O+6Pntc+gk1zv8bW+TOxZ+0KFBfkIaVRc7QcdQKaDT3CgFn+zjNY88V/aickzVoEREAEREAEREAEREAEREAEYkRAInOMQKobERCByiEgkblyuKpXEajpBCgy973luXKnmTV9Cpa+9jDg9dR0HJqfCIiACIiACIiACIiACIiACFQqAYnMlYpXnYuACFSUgETmihLU+SJQOwnQLqPZ8NGo17k30lt1QHL9xoBloXD3Duxc/huypn+C7F/n1k44mrUIiIAIiIAIiIAIiIAIiIAIxJiAROYYA1V3IiACsSUgkTm2PNWbCIiACIiACIiACIiACIiACIiACIiACMSagETmWBNVfyIgAjElIJE5pjjVmQiIgAiIgAiIgAiIgAiIgAiIgAiIgAjEnIBE5pgjVYciIAKxJCCROZY01ZcIiIAIiIAIiIAIiIAIiIAIiIAIiIAIxJ6ARObYM1WPIiACMSQgkTmGMNWVCIiACIiACIiACIiACIiACIiACIiACFQCAYnMlQBVXYqACMSOgETm2LFUTyIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQGQQkMlcGVfUpAiIQMwISmWOGUh2JgAiIgAiIgAiIgAiIgAiIgAiIgAiIQKUQkMhcKVjVqQiIQKwISGSOFUn1IwIiIAIiIAIiIAIiIAIiIAIiIAIiIAKVQ0Aic+VwVa8iIAIxIiCROUYg1Y0IiIAIiIAIiIAIiIAIiIAIiIAIiIAIVBIBicyVBFbdioAIxIaARObYcFQvIkAC/9rjwuk5loFxaONiQRGBChFI9gL5vttJIQKVSqBvgYWJO1zmGuPqebAg0Vup11PnNZuAGwAfXUU1e5qanQiIgAiIgAhUOQGJzFWOXBcUARGIhIBE5khoVb+2/JE3NN/CqHwLXQst1PMClA62uYCVbi/mJ3nxfZIXG/mLUFFhApGIzNRwDsu3cGC+hXZFFup5gAIL2OD2YkEi8FmKF38lSOipcFKqYQcHFFo4KdcC1ysezPBUwxmUP+QGHuDNrW4kAHgrzYtX0gPPsbEHODrXhf4FQItiC6leINcCstxeLE4E5iZ58VOSV0JWDO6QSEXmDkUWjsiz0KcQaFxsgQsi1KhXJHjxfbIXXyd7zfNMUbsIpHv5mbUwJteFcfWKsV7/bVG7bgDNVgREQAREoNIJSGSudMS6gAiIQEUISGSuCL34PreOF7hjhwu9C0P/0j+5YTG2+4rYFBUgEK7I3LXIwvidLrQsp9iZ8vJ5DYqxRj/SK5CR6nnqG9luNC2GEeom1K15IvP5e1wYm2OBj6YzGhSbRS//OCTfwjW7XEgJsc7ySaoXT9WpeYyq+s4NV2Rmqi7e7cJxuZapVA0W3yZ7cX8NvHerOi/V7XqH5Vm4fpfvA/3PBhKZq1v+NF4REAEREIH4JyCROf5zpBGKQK0mIJG5ZqafP/4f3e4CKyIZrC6bnuzFBjeQD6CpB+hZaGFQvmWqCcc2LEa2ROYK3wzhiMydiyw8tN2FtBLxbH6ir/Jviwvmb12KLIzIt1DfA1xQ34OVqmaucF6qWwc1WWTmPc4qZi6CTUvx4rEAldoDCizct8NlRExWw1Js/zPB9xlhNfN+RRaGFFhmkWZqihdP1MBq76q+Z8MVmW/a6QIXABisXP4q2YtliV4UAGjuAfoXWOhXYJln2t0Smas6jfv8ehKZ93kKNAAREAEREIEaTkAicw1PsKYnAtWdgETm6p7BwOM/ON/CzTt9qjGFnMczPMYmwz9o0XB6jgtvpnmMYKCoGIFQIjMtMv5vm9uIY8wHBTbaYvhHkhc4NceFb1M8qmSuWEqq5dk1WWSmDchFu13m/g9Wqf9ythuti4HdFnBtPU9A2xjKnIMKLDQvBj6i8qyoEIFwRGbaY1xXUqW6NMGLWzM9Ad+A6VRkYVAB8Ia9klahkenk6kRAInN1ypbGKgIiIAIiUB0JSGSujlnTmEWgFhGQyFwzk33bThcOyrfMpmEnNSxGXmjHjJoJoopnFUpktgU2DuuDVC+e02v+VZyh6nG5mioy862J17a6Qa/lWcle3BGg0pX+5P9X4p/xepoXrwXxa64emaw+owwlMnOB7O1sNzI9MN8n5zQoxlYtTFafBFfRSCUyVxFoXUYEREAERKDWEpDIXGtTr4mLQPUgIJG5euQp2CipHfcpsDA6z8JL6Z7STXYmbXOB1WS0WqDlQkWDG3Udl+vCwAKgebHPYoP2GrR6oFgajqUDrYVH5VkYnm+ZsVGs4Kvw69xezE0CPk31YHM5ogUPsZLu4DwL7YstUHtisfayBC++TPFZTgSLK3a7cGyuhZ+TvLgx04NWxcBpOS7DjnioaVH0+ne6B7tCCPK0uzg5xzJ2IxlemDF/l+zFW2keUxV+OndrA3Bo47KGyy9mu9G2GGajslMbFleoepyvpB+VZ2H/Qh9Lboi2OsGL/yV7MSXFa/xu/cMWkrjR43WZxbh2t8ucTz9uVrOzqpqLE+fscaGZB1jl9mJSHS8WUWFyBDd2umq3y/A/sWEx2hdZOLOECYtKN7lg8vFOmsdsXldexEteOcZh+Rb+kW+hm4Mp723ml28EFAWZC0VRiqPcwI4b2ZEzFxR4r5BHlgv4PNWDD1O9CPRpnLLFHdJ72MlwQoYHXzsq4HmtOh4Ln6V4qmwTT35uDs+zkO71PXvCiX/kWbixpBL26noe/OZ3X7GPwQUW7il5rYJ2C+V9rsO5ZkXy6uyfzwxuQsiN7poUWyZffG4sSfRtcsfnR3n11KzMPiHHhb6FFhp6YO6DjSXPvg9SPUHtivjZfn+rz5idzH5P9JrP/ZG5FloX+3yRaYf0TpoXP/AViHKCz3G+IUHGjTwwz7p5SV68luZBy2ILE0u4j6vnwQK/3NDC59aSt2PeT/Xi+QoskNEq5cQcF4Y4vk/Iktf8ONWLP4JYBD2+3fe8eijDY+xWTs5xmf/neY9meMz3yZW7XKbCnU/fb1K8eC7dU+Zz++5Wt3nuP13HgympXpyQa5l7md9tFNCXJHjxfprXfL+FinjIK8fI71Q+l7kHA+8vzp+byM5J4oJm8DeV+LznojS/k45qXGyeV2NzXOZ7mrZatNdamOTFq2mBv+f5XXjhnvBXG7gRIL2a7eDn6PadLmN7Mzs58PMxVA50XAREQAREQARqEwGJzLUp25qrCFRDAhKZq2HSACMqUnA9Ks+FFiW/1851bBJni8x83fyERsXlih+hCFAYvma3C8E0XIol9o/1YH3xh/hdO3yvwAcLiqKnNCw2r8j7B4WE+3e4jPgXLGYme3FvRllBge1tkZmC4eN1vKavQG9y8/jl9TymAjxQUNy5apcLgX5SUxhZkAgjLjL8RWbm6d/ZPrHIFrtDsQ90nL1fudtlBIVgwc0Cb6xXXEa0t0VmSidr3SiTD4rsZ+/xeeHawXyc5ZcXW2Rmm5syPbhzZ+D7I8tNu4Ni46UbKOIlr+Fsksn83pLpCbhJnS0yT071Yq3bi0t3783QnvsXKV48HMA/uKIiM+0neN8xrz8meY1wNjcp9oIN74tehT4xi4I8F5sowN8Xpvfu89tc6FBkGaH0Knr1BAinyPxsHZ8wH21UNK+8LufMzwQXj8qT0ijyvhhEbD80z8K1u1yGV6DgQswdmZ6AoqZTZL6nrsf4tVMYDBQUX7ngFigoQj643SfK+ge143+necxzkhFIZB6/y2UWCRnBFgjCyVPHIgsP7HAZkTdQcHhctCBP/7BF5lVumMU6Z3AhjCIzF9+cwUp4VsQ7wxaZeY22Rb6FjUDxcroHb5dj+REPeeXIuRHj8eVsxMj83lbXt0DhH7bIzL/zvyHu3OFGmwDf07xH+Zn1X1CuqMjMj/cnW3zfi/ye+DzFi2khFpzDuc/URgREQAREQARqKgGJzDU1s5qXCNQQAhKZq1ciKfCMzvVVAzsFC4qK4+r9vXkfd3fna6uMN9N8FbrRSDX8AcrqNfbEV6NZEbUiASi2gPZFwEk5LjTx+PyFKcBR4PIPvhr/7Dbfa9aM2UleU2G2wQUzB/7IP6ykepTWHoG8oSkKczMwBgXaT1K8Zjz0Nqa4xo3AGBT5KHj7hy0yUzCljsIW76X6Kr8p/o7NdaFZyQ9rCkWBBI6uhRae3O5jwQrA19M9WJoAI9pQ8GdOqPvampi/yOz8MU/hggJGNHFqjoXzSirH1rmB/6R5sNINZHp9laUcB2N5gheX1feYijY7nK/EswL8+TpeM29WJdup+6Wkao2Vm/RfpezkXznrFJntSuW30zxYlAhT4Tkq3wIFGMbiEkEx0P0XD3ll0STzShGOwQ0yuWDBamxWBFKAYgUuj/6a6DUewf5zsUXmvxK8aF1kmXbTUr1mwaRTkc/33F6kuaK+x1RKlheR2mUw75ftdpXee+ybFfafpfqq04OJ/OHef/zs8nkyOs9lPnN2cM3n9bTyhTi7LT+/zDfjzroewzhQ8H58vWQxhnPgIgU3LI00YpFXXvP8PS6MLbnJOfyPUz34LQHIccEIpfxMHZlnGXH3qQDPHlbePlby3GA3/LwuTPQ9+1hxe3yO71nOZ8cF9YvLVKI7RWYudPBZRyGOldNuL8xzkW+yMPhc4hsS/popddJXst1gJTOfOvSwtiuvOYaTcixzjv3sCiQy2/c4s3Z0o7LXCCc/fFa+VDIO9vNpyRsoHH6Xks+JvfYQqIrdFpl5LVZSL07gGyn0f/bNn9W4T2V48GcCcNFu39sm/pWzbGeLzMwH2fA7ZXKK11STdygGztzjMpYuDH6vccHGP+IhrxzT5btdGFOy4Mhn+lSz0OWbV/dCy1Rp85nMe/ei+mUtTpzfS7y/WNH+XpqPLXPB7zZWRzPIgTzKi0jtMqh78/lrf4ezb16B1+Jc+P/R/LdLOPej2oiACIiACIhAdSQgkbk6Zk1jFoFaREAic/wnm5YMFJGOynXtVXnK35W0RqCI5P/aOX9c8ge5XZ9FoY/t+Povq0vDiXQv8MZWtxFR+eP1unqeMt7O1IkooFCg4yvbFwUoT7tvB202fCN5IsNjXosNFMfkWvg2xSfMOcMpTs1I9oLig7MH/v7nGGhNwL+zGos/sp1hi8z8G+d/af29K6b5u5kiDFnzh/alAebx8HaXqeKkkEHxlvN1BisVKTbZ4S8yUww5t0QcfiTDY4SiSIO5+M9WtxEsA82D/TlFB75C7txY0CkyO8UTbhLJzSIZzor4R7e70KPQKuMf7RSZOYtrAlgf2NW17POuuh4wd/GYV9p8/LMkL6zIZWWuf4zMt3BLiVVAIIHUFuB4XqB7lLYsD5YIrOFYDUQqMvO6FAhZ5UpRiAKYHRRs+Bo6BT0uAkVy1zH3zPXwAgvOIkguYPC+omVHoDcPAt3XD213GbGKCyP/alD+2xXOxQd+pDh2zmFxgjfoWwb+14xFXp0LS1xAuD4zsO0ABcleBRb+G+Az/dR2F9gPnxtX1feYZ6kzuChEuwAGbTcm+FWFO0VmtplUx1Nmo0Pa25xRIoTflukxC3nOOCvHMtXYjCfqeIx45wxWKLNS2Y5AIvNnm91GDKfwf3rDcl5JKeeh5hTsA82DC36TtrnB7x4u8pzZcO/7xBaZueng5SXPaL4dw40iGc6qet5rvOcYxzUqxh7H94otMvMYPxN8FjqJcOH0+Wzfd18wy6l4yCs/n3xGMz4pWWD1/3xzUYhMKTpzcYHcneEUmQPdo+ydFfD87uOZJzYK/LaR3WekIrN9Hivc+f15SJ7PhsoO3gf2Ypk8wMv5cOmQCIiACIhArSEgkbnWpFoTFYHqSUAic/zm7QAKPCWVqU7NgIIyX7vnD+pyHBNMdROrG/1fBOZv0l8SvaZi84dyPBCdm9TRQ5EVYYGCr83TLoHhFCj5785NvHi9e8N8rd55HYp7FPn4u/OsBmUr/djWKSjQE5feuM5wiszBXim3RWL+0D66cfFeFcD0L31rq9uwZMUi+/APVn1RALYx+YvMToElkOgazp3oFHcnZngCiloUE97Z6vP45b3CV9vtcIrMZzQsNkIOgyIrRTlKR0c2/lvYGbfLZRY4/HPnHAdFVc7HPzgOijnUbFm1SnE23vJKve8/JZuZUTBlxXawsK0eAtlDOKs8z24QuPKWVikU0bjQc30Qqwj72tGIzM5xU3g7PM9lqslZvWoHvbinpfgWOFi1GSgorPE8+g87X5unmMw3ECgu/xmiEtu/Xy5C0cKHUd5Ck30exzxhh8t4fTuD9yevTQ/3L8rxn45VXin+UgTms+fC+mWtAkJ9Zp0CKJlzcSlQ2Is5XIvj2xzO57pTZGZFN+8vfyGRIjefTwy+tfKGn8XDq9luU4HOhSk+ywMtNNj3N/vwF5n5GZ5aYmlAsZ0sogk+l5hbfpdw48BA47CfReyf/vmsMrbDFpmdtjO8qz7f7Hs2O+dOofjNEibnNSjGasf3l1Nk5lw4J/9wbuLKxVPnomK85JXe5XzTgvfFv+oXB/WMp30P7TT4EaQllTOcInOw7zbnIgTf5PD36Hf2F63IbPfBxawDC3we2fy+sp8AHDUXmrhI/VOEi2XR3Ks6RwREQAREQATilYBE5njNjMYlAiJgCEhkjq8bgQVm/HHF158p0NpBQYhVcp+neEBrjHCD1b2scBvoZ69hn09vy4l1PQE3WrIrD4NVKNt9UDSgeMDwt1U4JcfCBSUVdKF+nAabE8UTiigUly4JIm6Q1EdbfBVwgUQ8p8g8tuHftiLOazq9Jf1tO5w/xMsTiJ2vc/uLzM4xBHsFO1RebV9USiLH+1XnOc+1xQcK5sc0LjZVlAynyDymUXHppnwUIChE2Bv52X3R6/PEXMv8qB/veE3aKTKX5wNLoZAeqVzYONlP3IiHvDorAcuzcCCPq3e5zOcy0Ov3tsjMzyYXWgLFvTt8G5LxM3d+kDb2eRUVme1++KnkWwSsbh6Ub5UugHCEtEvgBpG0R2F0LbLM5pishrZ1PR7hcQqkM5ICbyYZ6p7lcXuhiPfBGQ3Cs1qgsHlcLhfa/raycV6Lc+DmbLSd8Zc8Y5FXipd8plCvDWdhIBAHVmZy8Ypxe6Yn6MZ8zgU9/+ekU2SmwEaRPlDYvt6saHXadjjP56Z6zwTZsM8pqvqLzM4+nFXE4eTebuP0pOdmsc8FGYdzQcJfMLefr/5vAzBPXByhVRItkxjM2+QSYdzfQ9oWmbnocmaQzyLfBuD1GORJrnbEQ16pi39csogXqELZmRu+pcK3VRisQndusOv8bru/rgffBniTg/8d8UzJIhF9wfkGVbCoqMjs7JcLBfzvIS6YNXU8Vimqc7GMbziUTCuSW1FtRUAEREAERKBaE5DIXK3Tp8GLQM0nIJE5vnLs3PSKv6noR0iBZ06yd6/K2khHzR/cFF58/4PZQM+WsFk1xw19/Ku57B/ukVyLwgEFBDvG73QZf17KIvTxLGffvoCXcVbQUWRn9W6wsF9f5iu19CV1hi3w8vpHNQosAjqFUwoPFCDscFpdUCCkUBgonJYZ/iIzxXaK7oxoK5mf2uYyYmCoV9adVdOsGKRFAcMpMjMf9v5htCrhZoJczKAIb4c95oWJPrsUO5ysyvMYZiU9hUIGRXHbWiFe8mqL65Hc40whBXpn2CLzvCSv2QgxUNhCa3nCln1erERm5zi4PsMKZQo2doWys7LR3iyU53CMXybzjQlPGY/gSFixLcWh17Ldxtv71XSP8YiPNLjg1rMQ4NsdfQot4xVrR6Dqy1jk1SmKcswce6Th/ByyAjmYVZHTEuixDA+mOWw3nAIvN8T7TxB+tnDqz6M8sdQ5H2e1amVUMnOxg9ZJjPLsgrjA8WmJOPxNshcPON6AsEVm/00W39vqNvfE4xk+4ZHhfMb4z8dmVZ7HMC0bPiwZh7+IGw955QaarD6PNLhQ63wTwSkyX1nPYzz0/cNZuV3eoiLPi6XIbI+D3yC0HOJi2bCCvxfBAlm/RMpD7UVABERABESguhGQyFzdMqbxikAtIyCROb4S7hSZKch9ZaqXvWX8fys6alYGX7HLhSElXskLEr3mFWk7nK8gR3ItfxHE9laltsDq4EjDWSUdqlrL9n6mh+sxfiKgLTLTl5P+nIGiPJHZKSoEq4Rmn04h2V9kPj3HAqsFQ4ks5TGibzQ35AtVXc6NyjhmBv2jbR9Yp8g82rF5lz13bhB3miNP9rz9bTecrJwitv/Yna++O4X7eMmr08s23Hsz0EKFLTKzOviOIJYw+1pez970AAAgAElEQVRkpnY0tOQ1dHsTzWAiMzcupC0GKxYdNuPhItqrnb3QwAUN3lvcnK4iwbuavq3sl9WrDC6AcCHEjljklT7KXLhi+Feyhjt+u/qd7Z2LLP7nc+GIC0iMF9I9eM8hJDtF5mfrePChn5+y3Vcwkdkp7garVGUfznaV4cnsrKYN9dYArTkoEs9J8uJWx6JNMJHZnrvTg94pVvvbbtjt/UVsZ16MNdJm3+qcv3AfD3l1+ryHez+ynb+Q7BSZL67vMRvG+se+Fpk5Hn7vHZbns2+yLYAkMkeSebUVAREQARGoKQQkMteUTGoeIlBDCUhkjq/E8vf0ibkuU7HjdIZg5RF9KOkbW1GRxp4xf0RT2OhSYsvhtIjgT2v6XDJYVcfqumjigR0u9C+wzM72VSUys3D22DgUmWlDcGvJu71vl7zmHynTaERmbmLIzQwZ1Vlkroy8OsVIVr9Hu7FUPIvM+xX5KgD9N9TiwgGtBezX4ykynpC7tw8qmdOPm88eCs+RBqtBaYvC4tLyrBoi7ZftnQty/hYRscgr3/Z4ch+IzM/X8YB2EHbEi8j8UrbbVMBzZHwLomR9MuzURSMycwNDbmRoR3UWmWOdV6fIzGpvCubRRDyLzPZmphSW+RaDHVyA55tN76Z59rL+iGb+OkcEREAEREAEqhsBiczVLWMarwjUMgISmeMz4QkAhub7Nv7r7dj8hr+zfkjyiT58NT866ffvOTttIPwrnD4u8Tj2/6EfCTGnXQariyMVJqKxVfCvxuV4K1rJfGqOhfNKKoOjtctwvn5Pn9sbgtgqlMc3GrsM56aNlSEyV5VdRmXklaLqJbt9FaROMT6Se5xt401kZjE1bWooLvO1ejtYyc+FKnr7BtrsjO14nx5VUjHotKWg5QrtM/h2BXMRTnAzSVaz8znF+5BeqrEKzooVr6xY9bcpiUVenZ/XQJuJhjOPaGwVnNW4vEZFReZwxfLy7DI4DvtZzn++pp4n4kWHaOwyvk72YkIYdhnRVjJXpV1GrPPascjCcyXV7/4Cdjj3pt0m3kRmfq4pKPPZxbE5nGOMlQefXVz4sq2eIpmr2oqACIiACIhATSAgkbkmZFFzEIEaTEAic/wnl2IHN7+i16FTl6TQQ8GHwo/tuRvpbJy2B/6bIz2y3YWehb5N22gREY2g7bRtiHbjv7e3utEoRhv/RWuXcWC+hTtKqpCj3fiPuXk52w2+esyN+Fg5W2JRGnbabKEn3I3/uCjBqu5AG//Fyi4jnI3/AlWyx0NeexVaeLikWpUborHaNpqIB5GZui9tMFj1N8Rvo88lCV58WlK1HK44w+L3AwssjM610NtRRUhCFHVp48MFr2A+6xR/38z2eeV+l+zFfUFsRKLhbZ9ji4v+G1PGIq/xuPFfNHYZTm/haDf+I29nJXJ5G/cFy2csN/7z92SOVmSOl43/oskrXyyYvNUN/v+MZK/x+Y8m4kVkpoWX7RnPe8UOeuDbC2O0iVKIgAiIgAiIQG0nIJG5tt8Bmr8IxDkBicxxniDH8Pj7aniBBQrDFH+dwVfZ6XNpi5Zs6yhgDDrJ63f5xGuG/67zToE42tdxnZsTsfro3ih+CN+202Uqmvjz8iy/DfnsiTlfHQ5kRVHRSmZ6QP5nq9tslsgq8ocD2IfQ3oTCqV2s6e/JzLFy4z/6NjP4Sjwr0CKJY3MtU5XNeDDDV1XqH+le31h5yN9LuTIqmYMJHLSVpfjDanSKkbf7VW7HQ14phL6z1W28fbmZ48UN/hbkI8lLrEVm25pgZrLvcx0qaMVy6W5XqVcp21Oc4Sv0U1O9AX1WQ/XpPE4/1NG5LhyWb8E5HFr3cEM82lX4B9/CuGpX5FXidpF0qFlzQ0FukMig4M3N5OyIVV7v3OnCsJJnz4X1PVgZocjVthh4sWSMwZ4bHPNj212mepOP9RMbFqNkr0wznYpWMrMP+35a7wbooR5IqnthmwvtS740AnkykymfKxStOT72w41Cww0+O/lZ43OyvHE4rU7GZ3rABQQ7Ym2XwX6Z10BV/fTPp48+w3+zvHjJq73nARcRmQ/nZrXh5iXWIrPTFuqi+p6Q+0nwI3XPThf6Od7Y4thp8TSlZGGsor7w4bJQOxEQAREQARGoDgQkMleHLGmMIlCLCUhkrp7JZzXs0bkuU/nDH/2McxsUY02JwknBiZLL+2meoK+28/Xlu3e4jChK8eQCpwk0YIS3N7a6QdGSRbzXZwb/wdiuxPf1uQCi6YQdvh+QjCcyPOZ110DBH6eskGS1sTMGFVi4t0Q9p+jGii1nD9QgKD50KvIJ0bSzWO33Wn5FRWaOx54Hf9BzMz3/qiqnYM/2gURmCq7/t82N5iXephTGKD75B+d0ao4L36Z4SnPKNhT43s72WQTQeuCS+sWgP6Uz7LkG4l0ZIjNHz43XFvl59l6024WTStSyu+t68L2fZ2i85NW5OSH9xx/P2Pv+stlyenyFm0IOX7N3RqxFZtvLfLMLOKNhYFHQeX0na4ozrFqmwOwUK2PxpCMDilKj8yz0KFnoClSlzFuS/uEti4H5iV5c7/TdCDEQLuhM3OHCS+les/FboKcFNe3bd/r83hn31PWYTQqdEYu87l9omWcLg0Ikn4GB3j7gM5i2Rv73OM97ZpsLnYss8zbB1fU9WOonVDtFPvpjc3M+Z8RCZHbaIgV6BnOhkc8vOwKJzDzmXDhgdTz9kkvw7DVmPosHFQBvODYwZIML97hwcolwG6h6lxWsz25zg6fxTR3e+04alSEy8zvn5sy9P/Osqn0h27f4FOi7MV7yyjcMHipJAO+r8fU8Zb4P7MTw+56fR26g64xYi8xOexZ/i5BAH30O55Mtvi9sPq/4GeDCmL2PQCyeW+pDBERABERABGoSAYnMNSmbmosI1EACEpmrd1KpdfFHIn/8U7C0RWZWEPJv/IE+P8lrhB5Wj/Et1GYe32v1FBztuKOuB7MCbBzEvrlZHVuy+ZQUL35M8hqhheJzpyKfdzQFp2CvHjfx+IQDWzthVStff+V4OH5uJkU/UL7i7tx80JkZp1DNyja+9s1N2vijmdXBFDUY/HHKHef9IxYiM6/x9DYXKMVw/q+lebAkEWAB5VEl/pHUT2xdJZDIzHF1L7SMiGZry/RnnpHkBfdZTPPAbMQ4Mt+38SOFf//qSVbXscqOsdYNvJXGNr6KxyNLxsFjFMXoM2xbZfBvlSEys8qMxN9M82BhEkzlsu+1Z19O6KN5Vb3Awm085JXC6RMlixQc77KSCrqVbsBrAayYpZgzsmRBJ5A9SKxFZmfFO8Xi99O82OTyorjkI0u0zryevcdlLGUoLvuLmJX1hGM1J6ub6R//pN9nzmkvc0ump4woX96YKDKz4pVBkZ1C89JE3zOH93ibYgtH5P69uEYxios+/mJ0LPLKMTiFUep5H6XSj9hXKc6x8t44MtfCNylePBXg2cNnI62HmDqew8/rgkQYbty88MQcy/wzbUwuqF+MLL8FsliIzHzW0KqH4im/A95L81mdcEwcw0k5lnm+28+uYCIz2/P7gN8LDObkq2QvliV6UQCgqQfg4hGfMxTcubjkDIrxrKrms4354vOab7jwfu5aCJyZ4zL2Kgzaq3ABwxmxFpl5XbLhdwrFV1ZmdygC+Hni9xYj2P0bD3nl+C7f7cKYktUkfify/vw9EYYpOfP7ht8n/K78MsULPr+cEWuRmZ87vsFCgZ6fl+fSPeaNmpIXcMx3Rck6gxkGRWZW8nPxmZ8h57HKenapXxEQAREQARGozgQkMlfn7GnsIlALCEhkrplJdlbxlTdDCgvPpnvMj/1gwR+o1+5ymR+D5QUre/l6bKCgkHzXDjf42n2woGh2cqOylblsT3Hige0uI8AGC4omrGgM5BEbC5GZ12Ul6zW7fEKzf1CcZDUlN/tiBBOZeYwVkjftchkBs7xwVqfb7Ujg6l0uI2wHC3p031CvGJv8BloZIjOr1Sh0+BX3mqFRMLu2XnHQavp4ySsFEYpndsV9MK78CPAe869YjbXITLFv0jZfJXCgmJDhMQs18RpPbneBFY3BqkDLGzfviddKRKpQ81uS6AUXyILZNlQ0r7w+P2W0cODmn+W5Q/j7BDvHzgUXPjeC7XtIjZBvaDitIezzYyEys6/9iiw8uN1V+uaLc3x8U4WLc7SwYQQTmXmMc7h8l8tUswd/AvkqUv2rsnk+F+tYqR9s31Pe1a+ke0DbI/+Itcj83xSvEbXtinj/670cZBx2u3jIK3NACyYuFJSXD46ZQvokv4WQWIvMvM4xuRautFVlP6hcXOYmoAoREAEREAEREIHoCEhkjo6bzhIBEagiAhKZqwj0PrgMBV1WGbNCuG2xZX5M801taqBr3V5TTTctxWNsF0IFBYFj8yzzY7xVsQX+TmUxW5bbi8UJwJxkX4Wzs7rSv09W67HClR6nFBpY5EZBeL3bi7lJrGrzlBFFnX1wmKwY5AZU7YotU/XLN7xZyUjLCf/X5Z3nxkpkZp9diyxTPU0PVYpYrLakoPJ2msdUiNsbBJYnMrMfFulRpBhWYKFtkW9TR2ro5PFLos9ntjwPWF6LQg/FPLKk5rw6wWsEUFacB9rgrTJE5jMbFCPDa+GsHMuI51yM2OiCGcc7aZ6QlWnxklfmhK+Us6q+e5Gvktzt9VVrsir8l0TfPRbo8xJrkZljodhKy5SBBUDzYsvcL3bEs8jMzwUrExnBfMNDPW9YDclc8HnTpcg3f2qOfF5sc/mqzVkBSz/wUN7NFcmrc5y0KDom14U+hUCTYsssqvDeoNDNanPe7+XJ/lxoOynHZZ7HrDrnuPk54XOTtkasQg0UsRKZ2XdDD3B6jstUGzcs9tkg0S6Cb2XkuIAPS2wLyhOZ7THSAoTPL9qEcD68P8mDz2Oy4DPR8bLMXlPjvU0WgwuAZsUWEgGzUEDLHQqhzG+giLXIzMpeLpLRwuOwPJepxOZzdHGC7+0BvgEUKuIhrxwjLav49lKvkvuTa1C0nuJ3AivvZyZ5zVsl/lEZIrP9mWOFNe8TFk/b/5khkTnUHaXjIiACIiACIlA+AYnMukNEQATimoBE5rhOjwYnAnFJgJtPXlVSqUaROZoNp+JyYhpUhQncs4PioWWq189qGN1GihUehDoQgXII0M6Bi0iB7CMETgREQAREQAREQATimYBE5njOjsYmAiIAicy6CURABCIlIJE5UmK1oz2rfem5y9f2X0j3GO9fhQjEGwGJzPGWEY1HBERABERABEQgXAISmcMlpXYiIAL7hIBE5n2CXRcVgWpNQCJztU5fpQ2+Z6HPPoFBCwht4lVpqNVxBQhIZK4APJ0qAiIgAiIgAiKwTwlIZN6n+HVxERCBUAQkMocipOMiIAL+BCQy654QARGorgQkMlfXzGncIiACIiACIiACEpl1D4iACMQ1AYnMcZ0eDU4E4pKAROa4TIsGJQIiEAYBicxhQFITERABERABERCBuCQgkTku06JBiYAI2AQkMuteEAERiJSAROZIiam9CIhAvBCQyBwvmdA4REAEREAEREAEIiUgkTlSYmovAiJQpQQkMlcpbl1MBERABERABERABERABERABERABERABCImIJE5YmQ6QQREoCoJSGSuStq6lgiIgAiIgAiIgAiIgAiIgAiIgAiIgAhETkAic+TMdIYIiEAVEpDIXIWwdSkREAEREAEREAEREAEREAEREAEREAERiIKAROYooOkUERCBqiMgkbnqWOtKIiACIiACIiACIiACIiACIiACIiACIhANAYnM0VDTOSIgAlVGQCJzlaHWhURABERABERABERABERABERABERABEQgKgISmaPCppNEQASqioBE5qoireuIgAiIgAiIgAiIgAiIgAiIgAiIgAiIQHQEJDJHx01niYAIVBEBicxVBFqXEQEREAEREAEREAEREAEREAEREAEREIEoCUhkjhKcThMBEagaAhKZq4azriICIiACIiACIiACIiACIiACIiACIiAC0RKQyBwtOZ0nAiJQJQQkMlcJ5kq5SJ+bJiGzUw9sXzof8ydeUf41LBcOevZLuJKSse33n7Dg4asrZUzqVAREQAREQAREQAREQAREQAREQAREIPYEJDLHnql6FAERiCEBicwxhBlBV53OuBotR52I4vxc/DDuRBTt2RXB2b6mkYjMlsuNES9+Z87bueJ3/HzvRRFfTyeIgAiIgAiIgAiIgAiIgAiIgAiIgAjsGwISmfcNd11VBEQgTAISmcMEFcNmiel1MfiRD+BOSsHar97Fn28/FVXvkYnMLox4cbpPZF7+K36+75KorqmTREAEREAEREAEREAEREAEREAEREAEqp6AROaqZ64rioAIREBAInMEsGLUtO0x56D98efB6ynGnBtPRd7WDVH1HInIzAvU7dDd2GUU7MhGTtaqqK6pk0RABERABERABERABERABERABERABKqegETmqmeuK4qACERAQCJzBLBi0NSVmITBD72PpLr1sXH2V1j8wt1R9xqpyBz1hXSiCIiACIiACIiACIiACIiACIiACIjAPiUgkXmf4tfFRUAEQhGQyByKUGyPtxh5HDqffZ3pdN6d52L36j+ivoBE5qjR6UQREAEREAEREAEREAEREAEREAERqFYEJDJXq3RpsCJQ+whIZI4+5+kt26PFiDHYsXwRNs35OnRHlguD7n8TqU1bYdvv87Dg4WtCntN4wMGgMJ3RphOshETkZK3E+m8/Rtb3n4bc+C+xTiaGPTm1zDXC2fgvo3039LvtBXPu0n8/iKzpU4KONSGtDoY9MQWWO2Evj+mu596EnX8txqbZX6Eod0/IuaqBCIiACIiACIiACIiACIiACIiACIhAYAISmXVniIAIxDUBicyRpYd2F437j0SLkWOQ2amnOXnZa49g/Xcfh+yocb8R2P+ye027hY9ch+zf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IAIiUHsJSGSuvbnXzEWgWhCQyFwt0qRBioAIiIAIiIAIiIAIiIAIiIAIiIAI1GICEplrcfI1dRGoDgQkMleHLGmMIiACIiACIiACIiACIiACIiACIiACtZmARObanH3NXQSqAQGJzNUgSRqiCIiACIiACIiACIiACIiACIiACIhArSYgkblWp1+TF4H4JyCROf5zpBGKgAiIgAiIgAiIgAiIgAiIgAiIgAjUbgISmWt3/jV7EYh7AhKZ4z5FGqAIiIAIiIAIiIAIiIAIiIAIiIAIiEAtJyCRuZbfAJq+CMQ7AYnM8Z4hjU8EREAEREAEREAEREAEREAEREAERKC2E5DIXNvvAM1fBOKcgETmOE+QhicCIiACIiACIiACItr3Fm8AAByRSURBVCACIiACIiACIlDrCUhkrvW3gACIQHwTkMgc3/nR6ERABERABERABERABERABERABERABERAIrPuAREQgbgmIJE5rtOjwYmACIiACIiACIiACIiACIiACIiACIgAJDLrJhABEYhrAhKZ4zo9GpwIiIAIiIAIiIAIiIAIiIAIiIAIiIAISGTWPSACIhDfBCQyx3d+NDoREAEREAEREAEREAEREAEREAEREAERUCWz7gEREIG4JiCROa7To8GJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgCqZdQ+IgAjENwGJzHvnp8u/bkTz4UejYGc2Zl09Jq6T1+emScjs1APbl87H/IlXxPVYNTgREAEREAEREAEREAEREAEREAEREIHoCaiSOXp2OlMERKAKCNQ2kblxvxHY/7J7DdkFD1+Dbb/P24uyROYquOl0CREQAREQAREQAREQAREQAREQAREQgYgISGSOCJcai4AIVDWB2iYy9731edTt0B27V/+BeXeeWwa3ROaqvgN1PREQAREQAREQAREQAREQAREQAREQgVAEJDKHIqTjIiAC+5RAbRKZMzv3Qp/xTxvei1+4GxtnfyWReZ/efbq4CIiACIiACIiACIiACIiACIiACIhAOAQkModDSW1EQAT2GYHaJDL3uGoiGvYairytGzHnxrHweoolMu+zO08XFgEREAEREAEREAEREAEREAEREAERCJeAROZwSamdCIjAPiFQW0TmtOZtMfDe1wHLwp9vP4W1X70bkLfsMvbJbaiLioAIiIAIiIAIiIAIiIAIiIAIiIAI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EkgVmGVkXp97pU4/9XTd/u1mXf3q89Q675l7993Su/9MsJalvnn/zfr9+CojAgQIECBAgAABAgQIECBAoImAkblJUc4kkCowy8ic2t+9cu++PuTRJ87UwenH6skXz9Vzr52v1alTtb38df1w8QNcBAgQIECAAAECBAgQIECAQCMBI3OjspxKIFHAyDxn648//0K99N7FE+H+uHmjLl94u27d2M4ZWioCBAgQIECAAAECBAgQIDCpgJF50mLFIjCLgJF5liZP5vj3yPznr7/U9e+/rR8vfVK3rl+bM7BUBAgQIECAAAECBAgQIEBgYgEj88TlikZgBgEj8wwtykCAAAECBAgQIECAAAECBAjMLGBknrld2QhMIGBknqBEEQgQIECAAAECBAgQIECAAIGpBYzMU9crHIH+Akbm/h1KQIAAAQIECBAgQIAAAQIECMwtYGSeu1/pCLQXMDK3r1AAAgQIECBAgAABAgQIECBAYHIBI/PkBYtHoLuAkbl7g+4nQIAAAQIECBAgQIAAAQIEZhcwMs/esHwEmgsYmZsX6HwCBAgQIECAAAECBAgQIEBgegEj8/QVC0igt4CRuXd/ridAgAABAgQIECBAgAABAgTmFzAyz9+xhARaCxiZW9fneAIECBAgQIAAAQIECBAgQCBAwMgcULKIBDoLGJk7t+d2AgQIECBAgAABAgQIECBAIEHAyJzQsowEGgsYmRuX53QCBAgQIECAAAECBAgQIEAgQsDIHFGzkAT6ChiZ+3bncgIECBAgQIAAAQIECBAgQCBDwMic0bOUBNoKGJnbVudwAgQIECBAgAABAgQIECBAIETAyBxStJgEugoYmbs2524CBAgQIECAAAECBAgQIEAgRcDInNK0nASaChiZmxbnbAIECBAgQIAAAQIECBAgQCBGwMgcU7WgBHoKGJl79uZqAgQIECBAgAABAgQIECBAIEfAyJzTtaQEWgoYmVvW5mgCBAgQIECAAAECBAgQIEAgSMDIHFS2qAQ6ChiZO7bmZgIECBAgQIAAAQIECBAgQCBJwMic1LasBBoKGJkbluZkAgQIECBAgAABAgQIECBAIErAyBxVt7AE+gkYmft15mICBAgQIECAAAECBAgQIEAgS8DInNW3tATaCRiZ21XmYAIECBAgQIAAAQIECBAgQCBMwMgcVri4BLoJGJm7NeZeAgQIECBAgAABAgQIECBAIE3AyJzWuLwEmgkYmZsV5lwCBAgQIECAAAECBAgQIEAgTsDIHFe5wAR6CRiZe/XlWgIECBAgQIAAAQIECBAgQCBPwMic17nEBFoJGJlb1eVYAgQIECBAgAABAgQIECBAIFDAyBxYusgEOgkYmTu15VYCBAgQIECAAAECBAgQIEAgUcDInNi6zAQaCRiZG5XlVAIECBAgQIAAAQIECBAgQCBSwMgcWbvQBPoIGJn7dOVSAgQIECBAgAABAgQIECBAIFPAyJzZu9QE2ggYmdtU5VACBAgQIECAAAECBAgQIEAgVMDIHFq82AS6CBiZuzTlTgIECBAgQIAAAQIECBAgQCBVwMic2rzcBJoIGJmbFOVMAgQIECBAgAABAgQIECBAIFbAyBxbveAEeggYmXv05EoCBAgQIECAAAECBAgQIEAgV8DInNu95ARaCBiZW9TkSAIECBAgQIAAAQIECBAgQCBYwMgcXL7oBDoIGJk7tORGAgQIECBAgAABAgQIECBAIFnAyJzcvuwEGggYmRuU5EQCBAgQIECAAAECBAgQIEAgWsDIHF2/8AT2X8DIvP8duZAAAQIECBAgQIAAAQIECBDIFjAyZ/cvPYG9FzAy731FDiRAgAABAgQIECBAgAABAgTCBYzM4R8A8Qnsu8Dh0fp2VR3s+53uI0CAAAECBAgQIECAAAECBAiECtzZHm8eScy+SgwtM4GOAmeO1j8tVWc73u5mAgQIECBAgAABAgQIECBAgMDsAquqK9eON8/OnvP/8hmZE1uXuaXA4Xp9qZZ6veXxjiZAgAABAgQIECBAgAABAgQIzC6wqi+2m80bs8c0Mic2LPM0Aofr9Vu11KfTBBKEAAECBAgQIECAAAECBAgQIDCTwKrObzebz2aKdL9Z/Cbz/Ur5cwT2QMBXZuxBCU4gQIAAAQIECBAgQIAAAQIECNwlkPxVGTsKI7MfCQKNBPw2c6OynEqAAAECBAgQIECAAAECBAjkCAT/FrOROedjLulEAodH64+q6p2JIolCgAABAgQIECBAgAABAgQIEOgs8PH2ePNu5wAPervfZH5QQX+fwEMQMDQ/BHT/JAECBAgQIECAAAECBAgQIEDgvwLxA/OOxMjsR4NAU4HdV2eslrqwVJ1tGsHZBAgQIECAAAECBAgQIECAAIGWArvvYF5W9WHqf/R3d2lG5pYfY0cT+Efg7+9prnp1tdTLS9UzVXXAhwABAgQIECBAgAABAgQIECBAYKjAnVXVz8uqvquqL43LJ22NzEM/ax4jQIAAAQIECBAgQIAAAQIECBAgQIBAloCROatvaQkQIECAAAECBAgQIECAAAECBAgQIDBUwMg8lNNjBAgQIECAAAECBAgQIECAAAECBAgQyBIwMmf1LS0BAgQIECBAgAABAgQIECBAgAABAgSGChiZh3J6jAABAgQIECBAgAABAgQIECBAgAABAlkCRuasvqUlQIAAAQIECBAgQIAAAQIECBAgQIDAUAEj81BOjxEgQIAAAQIECBAgQIAAAQIECBAgQCBLwMic1be0BAgQIECAAAECBAgQIECAAAECBAgQGCpgZB7K6TECBAgQIECAAAECBAgQIECAAAECBAhkCRiZs/qWlgABAgQIECBAgAABAgQIECBAgAABAkMFjMxDOT1GgAABAgQIECBAgAABAgQIECBAgACBLAEjc1bf0hIgQIAAAQIECBAgQIAAAQIECBAgQGCogJF5KKfHCBAgQIAAAQIECBAgQIAAAQIECBAgkCVgZM7qW1oCBAgQIECAAAECBAgQIECAAAECBAgMFTAyD+X0GAECBAgQIECAAAECBAgQIECAAAECBLIEjMxZfUtLgAABAgQIECBAgAABAgQIECBAgACBoQJG5qGcHiNAgAABAgQIECBAgAABAgQIECBAgECWgJE5q29pCRAgQIAAAQIECBAgQIAAAQIECBAgMFTAyDyU02MECBAgQIAAAQIECBAgQIAAAQIECBDIEjAyZ/UtLQECBAgQIECAAAECBAgQIECAAAECBIYKGJmHcnqMAAECBAgQIECAAAECBAgQIECAAAECWQJG5qy+pSVAgAABAgQIECBAgAABAgQIECBAgMBQASPzUE6PESBAgAABAgQIECBAgAABAgQIECBAIEvAyJzVt7QECBAgQIAAAQIECBAgQIAAAQIECBAYKmBkHsrpMQIECBAgQIAAAQIECBAgQIAAAQIECGQJGJmz+paWAAECBAgQIECAAAECBAgQIECAAAECQwWMzEM5PUaAAAECBAgQIECAAAECBAgQIECAAIEsASNzVt/SEiBAgAABAgQIECBAgAABAgQIECBAYKiAkXkop8cIECBAgAABAgQIECBAgAABAgQIECCQJWBkzupbWgIECBAgQIAAAQIECBAgQIAAAQIECAwVMDIP5fQYAQIECBAgQIAAAQIECBAgQIAAAQIEsgSMzFl9S0uAAAECBAgQIECAAAECBAgQIECAAIGhAkbmoZweI0CAAAECBAgQIECAAAECBAgQIECAQJaAkTmrb2kJECBAgAABAgQIECBAgAABAgQIECAwVMDIPJTTYwQIECBAgAABAgQIECBAgAABAgQIEMgSMDJn9S0tAQIECBAgQIAAAQIECBAgQIAAAQIEhgoYmYdyeowAAQIECBAgQIAAAQIECBAgQIAAAQJZAkbmrL6lJUCAAAECBAgQIECAAAECBAgQIECAwFABI/NQTo8RIECAAAECBAgQIECAAAECBAgQIEAgS8DInNW3tAQIECBAgAABAgQIECBAgAABAgQIEBgqYGQeyukxAgQIECBAgAABAgQIECBAgAABAgQIZAkYmbP6lpYAAQIECBAgQIAAAQIECBAgQIAAAQJDBYzMQzk9RoAAAQIECBAgQIAAAQIECBAgQIAAgSyBvwAPk9kFbVIR5wAAAABJRU5ErkJggg==" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="550" height="323"><figcaption>example of Teleport behavior</figcaption></figure><p>Before Vue3, there existed another library: <a href="https://portal-vue.linusb.org/?ref=tech.jolimoi.com">PortalVue</a>. This library has the same concept and many developers from Vue community loved it and used it. Then the Vue Team was natively implemented on Vu3 with a new name: <strong>Teleport.</strong></p><p><a href="https://portal-vue.linusb.org/?ref=tech.jolimoi.com">PortalVue</a> still exists and has other features that don&#x2019;t exist in Teleport.</p><h3 id="simple-example">Simple example</h3><p>For a better understanding, here is a simple example. I</p><p>In a Vue 3 application, I create a simple component. In this component, I add a <em>&lt;div&gt;</em> with the text:</p><pre><code class="language-vue">&lt;template&gt;
 &lt;div&gt;
   First Paragraph
 &lt;/div&gt;
&lt;/template&gt;</code></pre><p>And in the <em>&lt;div&gt; </em>I add the Teleport component:</p><pre><code class="language-vue">&lt;template&gt;
 &lt;div&gt;
   First Paragraph
   &lt;Teleport to=&quot;#test&quot;&gt; Second Paragraph&lt;/Teleport&gt;
 &lt;/div&gt;
&lt;/template&gt;

</code></pre><p>In my Teleport, I add text in the slot and a CSS tag in props. This CSS tag targets an element HTML with the test in <em>id</em>.</p><p>After that in the <em>App.vue </em>I add ExampleTeleport component:</p><pre><code class="language-vue">&lt;template&gt;
 &lt;div&gt;
   Text in App.vue
   &lt;ExampleTeleport&gt;&lt;/ExampleTeleport&gt;
 &lt;/div&gt;
&lt;/template&gt;</code></pre><p>This is the result for now:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="data:image/png;base64,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" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="135" height="51"><figcaption>Result without using Teleport</figcaption></figure><p>And if I want to add <em>&lt;div&gt;</em> with the <em>id</em>:</p><pre><code class="language-vue">&lt;template&gt;
 &lt;div id=&quot;test&quot;&gt;&lt;/div&gt;
 &lt;div&gt;
   Text in App.vue
   &lt;ExampleTeleport&gt;&lt;/ExampleTeleport&gt;
 &lt;/div&gt;
&lt;/template&gt;</code></pre><p>The content in Teleport is shown before the first paragraph:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAABHCAYAAADofc4vAAAAAXNSR0IArs4c6QAAEc9JREFUeF7t3QO0JMkSBuCctW3btm3btm3btm3btm3btuedL9/mnNqa6u57u+6d6Z6pOOee3e2qrMqK/DMiMuLP3B49e/bsGSqpNNCkBnpUAGpSc1WzqIEKQBUQSmmgAlAp9VWNKwBVGCilgbYG0O233x6OPvro8MILL4TPPvuslCLatfEZZ5wR9t9//7D66quHo446qo9/RiGA/vjjj3DIIYeE++67Lww55JDhm2++CX477rjjwtxzz93HO1nvhWeddVbYa6+9CgF07733hlNOOSVcddVVYcoppwxDDTVU+OWXX8I888wT9t133zDyyCO31Lc025n55psvzDTTTK0DoO233z689dZb4dprrw0DDTRQ/K5jjjkmjDLKKGGttdZq9ju7pV09AHnhc889F6affvr4Lcstt1z48ssvw0ILLRSGG264OEF69OjRLf3qkw9tOQBNNNFEYZNNNgm77LJLLz28//774fPPPw+zzDJLn9RNw3ede+65Yffdd6/pwvIA8sBTTz01bLHFFuHdd98N4403XsN3lL3h9ddfD3fddVfYcsstyz6qsD0AzTzzzOHII4/slufXe2ihC5t99tmj27rjjjvCuOOOW9j+nXfeCVtvvXUYYogh4uCtuuqqYauttor3fvHFF2HbbbeNgGO13nvvvbDDDjuEVVZZJQ7aNttsE/75558wwAADhEEHHTSceOKJYfTRRw+XXHJJvDbDDDPE608//XR0OxdccEGYf/7547O1NxA//vhjGGusscIHH3wQ3n777U4BiEtbeeWVw6OPPhpmm222aPpvu+222IeXX3457L333mH55ZePrs83rrPOOmGwwQYL5513XrjhhhvCOOOMExZbbLEw/vjjh++//z5+w6WXXhoGH3zw2MczzzwzXHHFFfHbPU8fH3rooTDaaKOFzTffPD6X9Tv44IPDsMMOGy6//PKov99++y0+wzeef/75YbLJJovvpBMTl07EexNOOGFgeaeeeur4PgDybGNhzNxnYi266KLdDqhCAF1//fVhxRVXDAMOOGA0++utt15UWDL3ktfTTjtt2HjjjaOCP/rooziTDYiZsOCCC4YJJpggKpI8/vjj8dp2220XFbHMMsvEuIUA2mOPPRbvScrQ9qSTTorvN5A//fRTeOCBB+J1vt4zxDaksy5Mm8MOOyzsscce0Z2NOOKIMd5jbblrYOauDWLqj38eeOCBsZ8LL7xwGHPMMSMIgMFgGTyzf9111w2PPPJIWGCBBcKHH34YY6wbb7wxrLTSSlFH/htwTIbTTz89xmInn3xyfOcBBxwQ9tlnn/hOuh9mmGEiCMh0000XdeaeP//8M4LtjTfeCC+++GIcEwBKOht44IHDGmusEXiMJ554ou8AyFvN/sMPPzwAkwB6zjnnDNddd10YaaSR4jUDaWaNPfbYsZNmxWabbRZRD1zPP/98mGaaaeK1v/76K36wGTbjjDMG1svsJWboVFNNFZ/J8uT9+fHHHx/8aUMhs846a2wzxRRTNAUgSjcZDAhXlhfAWHvttcOvv/7aC0ApQP3777+DyZPiwtRW/7XZddddw0EHHRQuuuii8Nprr8XLn376aRhjjDGCgN63JQCxoKwrnbBuWWHJWdVbb721F4CAME26J598Mk6ip556KuozrzMrs/322y988sknfQ9A6c1ff/11nJGHHnpotETnnHNOuOaaa+Is8VGsBBF0W0pyedwD024WZeXKK6+MbszgJKX98MMP0Yy75nl5ZbBEXAw3yMWtueaa/2nfUQskkB566KGji2BVWc/Ud6Dx57qZy9oZ2GSB8iscLpr7oRsg4K5YsN122y1aCW4H4IlJRidpsPMAShNMOuKZZ56Jwf3DDz8c3TO3mixQFkDCC5ZTn41DXmeNdNKVqCp0YUWzYqONNgoPPvhgEBDy98zkd999Fwc/K1dffXUEwldffRU/Misp9sgCCNAorZYysgAyMOuvv374/fffwyCDDNKUBcorj+uUmnj11VejFdUPK816AFpiiSVivHT22WfHx7FA2gCQ580xxxzRonI93JNvYPn0uQhARxxxRIx5tDGxWCATshaAuF7xlXhs6aWXbj0AAQsUZ8WMu+mmm2Is44+S0qzK3ifI48Ioat555/3PM9KKiHIMFnnppZdiMPjss89GhdezQHfffXdcgpdxYXkAcWOsK0tBOgKgUUcdNbbZYIMNegOQH4DcwoK7F9iKt9JipAhAYhqBuMUCaQSg5MKAXqDdchZIfMGlSL4RbgZgrH4EjmIBAHDdCoIZF+cIKM0ywBE3GQwBJ/n5559jUtIKT5zERxMrDLGNAJXUA5AAUrAoHrvwwguDgJF7NYNrZaKLlvFZEMkPrbbaauHNN9+MsQpgmCz1LJAJ4jtOO+20CDz9oRsWiHUWC3G7dCHIFWRbXFh1FgHIQsLv9EBvQgH6rGWBuF8x0j333FOos77uwqw4WBsziEnl68U1cidpJUbhBl+wbHUBUIJdQTX3teOOO8YPpES/Wa3x12IZM4yCXBOTaEfJShOsn4EUEww//PDxOVY2BovbBAggZsUE4u4VbAKkfFBWuIRjjz02XHzxxWHxxRePrip/jwFbdtllI4BZQjGaAXWfJb53cVd+E38RCwt5MjGTVaI++WYuTdzHxdFPVgTuYjjfk3JXm266abRMvkUfxDbAKE3gXn0HJpbZZJl88snj6s5EtIozOY2TPiadGQvvELSzrlIQ3SltXQvrTsU0+2yBMCvGgicxmJb2WdfdmecDECvJwrWaVADq4hFhaVgNOaEkEqosbDbt0ZnXAlB2FdaZtt19bwWgLtawgZbPEjgTceFOO+0UV68333xzU2+rANSU2tqzkYyzeCklHL/99tsIKOURi43OiqSgoFysJAYVe7WSVBaolUajDftSAagNB62VulwBqJVGow370huAllpqqZhrUIaQe1AXko9JhVE5IYlARcPuEsGmuptMq1xUGUH31Fd5FbmsSrpWA70ByBJUNjUJmsZcc80VK8xEVV3KvQyAJAaR1tRzikQCUOVZXU0poIwAouKnySABWEnXaqA3ACk/WIrWApAUP9ISOkQzYnXCmgGpImR3iqSeEgErJsONWpEv8Hbn+/uHZzeMgfIWKCkFRRMRy4AYGBZJHUuKXcZUmh2hTJHQ0hNvBWEKmUt1WmZWat6/Z0WlGeFdGl45gKVSVtBOck6xlhVURGRRUq2taLBQLJRNuGDWTt1M2j+J2pPyiHKNsohno3jgQXF3ja7n36lkok41ySSTxHrakksuGYvEyiwYCPri21IJQj2L3rAMEj9IzRAnXW0P60C/bGbIc4ZaBZxNAejjjz+OA6t+pLDImsh9qHNxOepWO++8c3jllVdi4VUckth17qEU9IZaFggZC7gSgChLDQ4guSQgw9HZcMMNI/+mSFg66X/FXqIOZ1BwbbKCJWmQE8FeDU4SEJ/HQDe6nn+3/qG9KFukuqEamknge5Hu5IrUsAiqqxpdAhCQmZDcN92x1qr7kpGtKE0BiJJRSs0gIuhWADRjVZ0Nnuo92oOZ494RRhgh3lsGQOihgnyiiMmyILgViUFEe8DFJonMps8q+kkABKWERSUq/gqSEn+Kko2u59+ND6QIe+edd0bqCSaDvqKikEYAUoxFc8VwJCYJ4Debxe5u0DUFIFV45ho/mJgpVkyAgudLuANuC9WCSU7SVQASp8nsMv9FYiazconorvpvRQkY/moByO9mPUoKMlgeQPnrRe+WeZ544omj9ZNJFsCzIo0AhBkgJKBDDADCGvn3yy67rLux0NTzmwIQGgJrw/TXEispg8yMI4ClgewTAAIWlirxaVIfWQJAT3xlvxcBBM9JUZSlbXS96PuBBn2Fq8dU5I5QMBoBiBtDy8A9R+9oB2kKQOgKAk05ocQrzn6sgJHfFwvhIosLBJWkTwAIrwhrMpHWUt/EYViEydUWAQj4rNoE7dxNHkD560WDLBAGBExD+smS99Wz6OCWW26JTbMxkEmGY4SPxX22gzQFIDMY+UquhjvAtLNlOOVsBHwCWIGuABuAuLRJJ5005mTERgZ5kUUWKdRRrSA6GwPVc2Hel/aXZV8g+Ear4N6Q2IoAxDW7bpDxvfMAyl+3EhWz+L5sigBDkUtPu01SP0wk97PegCo2k3tLQTSLBVQ4RGnnSla3rQaqmgCyKrH7QpBqCWzAzMgUgAKA1QofbQcBS8Pks05oolZM2HVpaWtV5bqlPtafoFLALU7IEvO5uxNOOCHGDt7HFeiLAQFKlk/QK67CaHQfeikx86UQxEVmv5Vh2nwn0Nc35HXtWEjg9xsXYy8bi4pZaI+X5GkCWL3rtQCkj9iAclFZsdUGEV4wb2uOxYZVqvQCwAGSCcj9WoBgc+655569Nla2DYBaraPd1R8WhsXLx0vpfY2ud1e/2uW5DV1Yu3xIs/0sCpKzz2p0vdn39ivtKgDl8kD5ga0AVB/q/TWA7r///hh7iH3EK3JW2eNeGl3vV6xIme/orwFURnFV2/9roAJQhYRSGqgAVEp9zTdWe5NGUHuzRbxdpTcA5c8VlOyyNQW1wMkV6BdyQvItKtuKll0tzuZBYZDBlYOyI0GOB7VE9T2xI7v6vX36eTLlqvL9FIAosdZ+clllhUEAso3XtmZJv2ZEQg2tod6ReU7tkFUGJoVGvCJVacnGWmzGZvrSt9r0dwDCz3EcixJFWZFZlp1Ox+IVPS8LINcVQh38oKYFWN0t9nQpO+DyFNX8yr4fgEwItJN2lcIYqNGJFtLzlMoSsCLqOir0Ks7JYiha4rL44/78cYUOQuCasAWVRdR7lB6AJS95ACkz4OooP3Ch3K00v4MdELjQS7i4Wv1RFql1FqF3q0EpK6BPmCwAy2WrT6lhqf0phSitODhCvazW+YodYTMCkDJJOo9R9Z5efFO7SIcBpAZF+elUU5V2dEwAIpSh/gUcKsq4OEBDkemgAfekCrnnqPl0xgJhQKp7UfoKK6wQzx9MdTjvExsZVDFTUX8UWGudRagGBcysm1qVwqs6lFpdolbIEckbcaWA5RiVeucrNmIz6iPdyDcpxAoHVOGd0pE/3a1VAVUXQHgxaVuNGSlorgegbECIfG+wFF0RuRIfJimiswBifRRhJf0EnWKxrCTrBGTOUczHF43OIky0CsVhFXuCPaBSnkAPQIkRUPS8/PmKjdiM+T7ienunffR41e0gHbZAPpZ76iiAfDxFqMhTvOo3einqK+kogLgxLor7QxW1Tzy5O64KUV51HSuSe0lH9xYFqLg8tc4iBHIsRCvN1EcuVqyWuDlZAKXBrXe+YiM2Y76P3DAmYzp5rJ8CEII8k849kSIXVrQkdY6i1RuTj9uL5iDG6CiAUkyVVyYLgPTuECZliGSB6gGo3lmEODeAY+cIV4ffw5JZaSZrkAdQo/MVG7EZ+ysA5QewIwDCwUnHAGMpAg2LwRqVBVBakSWSfEcA1OgsQhYMD5obIeKdxAvy33kANTpfsRGbsQJQLojOWyAuy/YeFkfGVXDrSFyDYjnuuF1BaC3Jr8Ky94mF5IIQ1hDN0ilg9SxQvbMIxR9yUqisKQZCdEN6S8ey5AHU6HzFRmzGfhJAchKWpgbathSMOcxDGwST4PNK7tmibNlp+Sw2EfOkrTDiEpsMrcysbrgyMUY6LFt7qXwrJ1aJu0jCmugD98QaABp2Ip5xVjyLxfB8bgdAbFjUJ2mGfH/qnUXoHfaOpcO903us8sRatnZjQQrkpQNMgnrnK1qhAlAtNqNVo/gKcH2r99MHvWiHFZk/0LwVY6KqFvbvqEiQyseg8aYgXcxm4yQrKZ/VWekf2IwVgP5FBdfFYqUdtAkssuUscNro1xkQ9Q9ktApA/yLCKtHJ7w6OSMIacY0y7vkT+TsCpApAHdFSP3KPIF9mXEwiC+z/EMSViWXS9prOfGr/wmasLFBnUFHd25sGKgBVoCilgQpApdRXNa4AVGGglAYqAJVSX9W4AlCFgVIaqABUSn1V4wpAFQZKaaACUCn1VY0rAFUYKKWBCkCl1Fc1rgBUYaCUBioAlVJf1bgCUIWBUhr4H+HuSv6Z6/wQAAAAAElFTkSuQmCC" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="144" height="71"><figcaption>Result using Teleport</figcaption></figure><p>And if you want to show the second paragraph after the first text is possible and very simple! Teleport has another prop: disabled. This prop <em>disabled</em> the teleport feature. For example, if I add disabled props on my component</p><pre><code class="language-vue">&lt;Teleport disabled to=&quot;#test&quot;&gt; Second Paragraph&lt;/Teleport&gt;</code></pre><p>Now the second paragraph is after the first paragraph.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://tech.jolimoi.com/content/images/2023/06/image.png" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="232" height="50"><figcaption>Result using Teleport with disabled equal true</figcaption></figure><!--kg-card-begin: html--><span style="color:#d36363;">&#x26A0;&#xFE0F; In my example I add the target of my Teleport in my App.vue but the target must be available in the DOM when the Teleport is mounted. In this example and the next example, it&#x2019;s the case. If possible, a good practice is to add the target outside of your Vue application. For example, you can add the target in your index.html.
<br>
In the Vue3 roadmap, a safe mode is planned to correct this problem. you can see more detail here. &#x26A0;&#xFE0F; </span><!--kg-card-end: html--><h2 id="why-use-teleport"><strong>Why use Teleport?</strong></h2><p>After discovering how to use the Teleport component, we will now see why to use this component and what its advantages are with a few examples.</p><h3 id="reason-1-manage-the-dom-outside-of-a-component-scope">Reason 1: Manage the DOM outside of a component scope<br></h3><p>The first reason and that you need to manage the DOM outside of your component scope. With Teleport is possible to manage the props, data, method, etc. in your component and display the content elsewhere in the DOM. </p><p>It&#x2019;s very useful to avoid many problems with CSS in particular with position,<em> z-index</em>, <em>overflow</em>, <em>display</em>, etc., or to don&#x2019;t have a problem with the HTML semantics.</p><h4 id="example-modal-component">Example: Modal component</h4><p>A good example of that is if you want to create a modal component. With this component, you can have many problems with CSS because we use <em>position</em> or<em> overflow</em> attributes and with the HTML semantics. </p><p>Let&#x2019;s build a simple modal component:</p><pre><code class="language-vue">&lt;script setup lang=&quot;ts&quot;&gt;
const props = defineProps&lt;{open: boolean}&gt;();
&lt;/script&gt;

&lt;template&gt;
  &lt;div v-if=&quot;open&quot; class=&quot;modal&quot;&gt;
    &lt;slot&gt;&lt;/slot&gt;
  &lt;/div&gt;
&lt;/template&gt;</code></pre><p>Now if I add my Modal on the button:</p><pre><code class="language-vue">&lt;button&gt;
  I&apos;m a button !
  &lt;Modal :open=&quot;true&quot;&gt;
    &lt;p&gt;Waw ! It&apos;s an awesome modal !&lt;/p&gt;
  &lt;/Modal&gt;
&lt;/button&gt;</code></pre><p>We have two problems:</p><ul><li>The semantic HTML it&#x2019;s not good and if I click on the modal, I click on the button</li><li>The style of the button can have an impact on my modal </li></ul><p>If I use Teleport I can resolve all problems with that. </p><p>The first step is to add a target element (on my <em>index.html</em> for example):<br></p><pre><code class="language-vue">&lt;div id=&quot;content-modal&quot;&gt;&lt;/div&gt;</code></pre><p>After that, I can add Teleport to my Modal component:</p><pre><code class="language-vue">&lt;template&gt;
 &lt;Teleport to=&quot;#content-modal&quot;&gt;
   &lt;div v-if=&quot;open&quot; class=&quot;modal&quot;&gt;
     &lt;slot&gt;&lt;/slot&gt;
   &lt;/div&gt;
 &lt;/Teleport&gt;
&lt;/template&gt;</code></pre><p>So we have that on the result (I add style for my button and my modal):</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAc0AAACXCAYAAAB3JwA4AAAAAXNSR0IArs4c6QAAIABJREFUeF7tnQuYVGX9x78zOzuzF1hgCRBoFQR0HyEgUFIUE/ubmBoaKplJRWJkmln9M7uX/SszK/OWl9TwUTPj+WtiQmSYF+whISAwEvwLIaIQKyzsfXbm/3xf9yyHYS5nZuecOTPzfZ9nntndOee9fN53z/f8Lu+ZQDwej0NFBERABERABEQgI4GARDMjIx0gAiIgAiIgAoaARFMLQQREQAREQAQcEpBoOgSlw0RABERABERAoqk1IAIiIAIiIAIOCUg0HYLSYSIgAiIgAiKQVjRb98fR0hxHVzugHNviXCyBAFBZBdTWBVDTP1Ccg1CvRUAERMAnBFKK5r49cRx4W7tRfDJPeelGv0EBDBgs4cwLTFUiAiJQlgSSiiYtzLffkmCW4ooYNEwWZynOq8YkAiLgDYGkorl7Rwydbd50QK14SyBcDQwZGfS2UbUmAiIgAiVCIKlovvFqTDHMEpngxGEwxjlijESzRKdXwxIBEXCZQFLR3LEl5nKzqr6QBEaOlWgWkr/aFgERKF4CEs3inbucey7RzBmdThQBEShzAn0TzVgUy29sx8YDwOjzazF7SgBbF7fgsbVxDD2zBh87pfAWzdbFB/DYWqD2xGosOLuidKY7FsXS/2nHpk6g8ZJ+mNXofGgSTeesdKQIiIAI2AnkXTS3P9GCxaviaDi3BnOmlZ5odqxtw93/G8eky2swY2QPylg3nru5DauHRnDlJZUIebHGeMNyQzs2tgYw/tJanHGM80Ylms5Z6UgREAERcFU0dy1vxUPPxjB6Ti1mTy78nsD8WppxbHygBcu3BDHVLprbO3DvPV1oPsZL0ezGipvasK45gEnzazFztPOFLdF0zkpHioAIiICrotn0bCsWLY+h8eJ+mHUcsOnhA1j6MjD8zGpMj3ZixYvdaIoGMPz4CM45I4idyzrw7JputIaCGDUzglknVqS21Nq7sW5ZJ9Zt6kZTKxDqF8SoE8KYeWoItSmMWks0606swhmDonjuhSh2tQZQd3QIp58fwah+AGJdWHJ9B7bEDhXDncta8cjzMYQmRLBwNvD4Dzuw3Z4jNTKMs47qwlMrD93T2usubY5i1fIubNjSjeZWINIviBHHVeKkD1RiaNU709DL56xqnBrswornevp3VAinX9DTv2Rr1rJu9wYx9bIazGhwvrAlms5Z6UgREAERcFU00RpD034gMiiI2jCw5dEDWLIeqB0eRCQYQH04hq2vxRFFAA3HBLCvLYChwRi2bIsDwSCmX1GDacOSqgQ2PtCG5a/EERkewoQxwPY1FBgKcg3mpoifWqIZqQ8iUhHA0OFA0yvdaGoHQqPDmDc/jDonojkniI3LOrF6VTeaY8DQCZUYPrICE+q7sfr5KDZtjwMDKzC+MYiG4yNorO3C0js7sGkvEBlWgdEjgX1burGzGQg1hHHRZWEMDdr4jAyioi2AEUcCu17uRlMnEJkQwfy5lYikEM2Vt7Zh1Z4gpi2swfThzhe2RNM5Kx0pAiIgAu6KZgJfS7QwMIQ5V1WhIdQT/2sCMKQSc6+IYDi6seLmNqzbi9Sx0M4oVv5vF3bHAhj7X1UYPwTY9XQrHnomBhwVxvzLwqhLMre97deFcN5VVRhVBXRsaseiB6NooUhfWYNpgx1YmnMrEUohrk3PtGLR0zGg8aB7dteyVjz0fOzgGBnobO7C47d04LV2YOyFtThnIhOn3klUQr8QzrmqCmNrgJaX2nDf492IVoVw3nVVGJXUio5h1e2tWPlWzxiGOF/YEk3nrHSkCIiACBRENCOTq7BgTgghxLHpwRYs3QTUHl+FBbOpJnFsvL8Fy18Fhn6gBh87LXMCUTQGdLzUhruf6AaGVWLelRHUpxHNg+0DiHZhyQ87sKUTGHtxP5zTmG/RjGH1Xa14bjtQd0o15p9pZe0eHGfttGosOLeiVzQP6d+ODiy6qwtNwQrMuq4ajeHklrdpY0cQM66pwdSBzhe2RNM5Kx0pAiIgAgURTfuWjy2PHMCSDXZBOSik9R+oxrzTkm0NiWPnyg48+2IUO/cmTOKwSnzsygiGphHNuunVmH9WT729mad4J2FpYjRzTDMbS9OKNzYd7jq2xh6aWIWFF4bwerItMW91YNHt74jmGddWY3xP/PPQ4cWw7t5WrNhWgZn/XY1JjM06LBJNh6B0mAiIgAgkEMj7lpNEwsmyV3MRzY6X23Hvw1F0hIIYf24YE4YE0LGpA489GzOWZibRjEypwoLzaekC6OyxNKN4J2HJsjSjAUy6vBYze5Jqtj/egsUvxd9JBMpGNJHK0oxh3f2tWPHqwX2jSbN7HYlm7mtZopk7O50pAiJQ3gSKRjStrSwYGca8hWHUI44ti1uxZG3cxA2NaCbx6h4WUw0fGtOccTVdmwcf0jD87BrMPTEItEex/LZ2bNyLw0WT4mrb5tEb0xwdwYL5lagF0BvTpKAvjGBoT0xz8c0d2N4ZQOPFNZh13MGY5iEPX3AkmnE074yhPQZUDalAXVIXbvLFLdEs7396jV4ERCB3AkUjmuahAou7EQ0G0DAthPoD3XhtHxDaEUMTghh9SiVmnFF5WFzTyt6N1AUQqQ1ixPCe7NR2INIYwbxLKHJxbHm0FUvWx4FwEKMnBIEd3WgJArt2xhE6LoKFFzMRyNobCYSGVWDsmBCmnVWJyKqe2GowgOETKjD2+AimDoli6R0d2NQMRIZXYOzId7J2mT0bGRPG3Hlh1AfRG9PMWjStpKSoHm6Q+/LXmSIgAiKQHYGiEU3EYtj0ZDtWro2hGQEMbazEzLNDaFnejqVrYsDASsy+OoKGBGvTcgXXn1aFUyu68Cz3iXYGUH9MJWbODqOhpgfYAWbndmLd/8XQXRXEqJMjmB7qxKInuw/Jim1e047HnoqiKQrUHhXG7HlhDO3sxsqH2rGG22aqgjj2/Gqc0RgAuE9zWSc2bImhmSJdF0TDxEpMn1mJ+p7HBuXsnpVoZrfSdbQIiIAI5IFA30QzDx1QFd4TkHvWe+ZqUQREoDQISDRLYx6zGoVEMytcOlgEREAEeglINMtwMUg0y3DSNWQREIG8EJBo5gVjcVUi0Syu+VJvRUAE/EMgqWi+8WoM8UOfQe6fHqsnfSIQCAAjxmR+4lKfGtHJIiACIlCiBJKK5u4dMXS2leiIy3xY4WpgyEiJZpkvAw1fBEQgRwJJRbN1fxxvvyVTM0emvj5t0LAAavoX/ntOfQ1JnRMBERCBFASSiiaP3bcnjgNvSzhLaeX0GxTAgMESzFKaU41FBETAWwIpRZPdoMXZ0hxHVzsU4/R2XvLWGmOYlVVAbZ0szLxBVUUiIAJlSyCtaJYtFQ1cBERABERABJIQkGgW2bKIK625yGZM3RUBEbAIBOj6KvIi0fTxBEogfTw56poIiEBeCBSbkEo08zLt+alEIpkfjqpFBESgeAn4XUQlmj5YW07E0skxPhiKuiACIiACGQk4EUYnx2RsyIUDJJouQHVaZTohzPUzp23rOBEQARHwkkA6Ecz1My/7b7Ul0SwEdXALz+F7YBP/xt9TiacszwJNnJoVARHImkAqUeTfEz9LdqyfrE6JZtbT3/cT0gmmJZTWMYnCKbHsO3/VIAIiUBgCdvGzC6b1s/W5n4VTounx2klmTVpdiMX4oPw47O/8mSWV1SkR9XgC1ZwIiIBjAqnEz/p7MBgEX/zd/t7rCk3YouIHi1Oi6Xj6+35gJsGkQPIVjUbR3d1t3q2/2c+VUPZ9LlSDCIiAtwQSrUxLMEOhECoqKsB3629896twSjQ9WjepBNOyIC2xpFB2dnaaBVRdXY1wOHyYz9+jLqsZERABEXCNAK99vNa1tbUZA4HXOl73LPFMdN/aO1JIi1Oi6dqSOLTiZJaiXTBpWXIB8RWJRFBXV+dRz9SMCIiACBSWQHNzMzo6Ooxw8kXL03LXJotzSjQLO1+ut57OyqSFScHs6upCe3u7WSiDBw92vU9qQAREQAT8RGDPnj0mHFVVVYXKyspDhJP9dJJl68V4ZGl6QDmdlUnB5It3Wa2traivrzduWRUREAERKCcCdNM2NTWhpqbGeNtobfKVyk1bKGtTounyqszkluWdlWVlHjhwAKNGjVIM0+U5UfUiIAL+I8Br5datW9GvX79ea9OeXesXN61E0+W1k0k0rVgm77L279+PcePGudwjVS8CIiAC/iSwefNm9O/fvzcJ0o+xTYmmy2snUTTtDy+w4plM/qFrlsHwxsZGl3uk6kVABETAnwQ2bdpkkiDpok2WEJT4BKFCuGglmi6vHfuTfdiUXTQT45n79u3D+PHjXe6RqhcBERABfxLYuHEjBgwYkDKumeiilWj6cx5z7lUq16z9iT/cn8QkoJaWFmNpTpgwIef2dKIIiIAIFDOBDRs2GEuztrbWJAPZ92xaW1A4vsQHJXg5ZlmaLtJO55rlZ9ZTfyzRpKU5ceJEF3ukqkVABETAvwTWr19vLE27aNozaBOfUZsooF6MTKLpImUn8UwKJ/dn0tKkaE6aNMnFHqlqERABEfAvgXXr1vWKJvdrWttO7A86KHRcU6Lp4vpJFc+03LOWpUnRZCLQ3r17MXnyZBd7pKpFQAREwL8E1q5di4EDB5qYJkXTei6t/YHuhY5rSjRdXD/pRNPKnLXHNCma733ve13skaoWAREQAf8S+Pvf/25EM9E9m26/ptfJQBJNl9aPkyQgu6VpuWclmi5NiKoVARHwPQGKphXTtFuaiV8flhjL9FI4JZouLaNk8Uw2Zc+ctZ45ayUC0dKcMmWKSz1StSIgAiLgbwJr1qw5xNJMfAat9ZVhhYxrSjRdWkOZMmftXwVG0eQj9JgIJNF0aUJUrQiIgO8JUDRpafJRetaWk8SvCit0Bq1E06VllClz1h7TtLJnaWlOnTrVpR6pWhEQARHwN4HVq1f3WpqJ7lm/ZNBKNF1aQxJNl8CqWhEQgZIlINEs2anNPDCJZmZGOkIEREAE7AQkmmW8HpyKJr8WzB7TlHu2jBeNhi4CZU6AommPadoTgeSeLfHFIdEs8QnW8ERABPJOQKKZd6TFU2EuoslEoOOPP754BqmeioAIiEAeCbz00ksmEcjKnpWlmUe4fq9Koun3GVL/REAE/EZAoum3GfGwPxJND2GrKREQgZIgINEsiWnMbRASzdy46SwREIHyJSDRLN+5h0SzjCdfQxcBEciJgEQzJ2ylcZJEszTmUaMQARHwjoBE0zvWvmtJoum7KVGHREAEfE5AounzCXKzexJNN+mq7mIncMcdd+DnP/+5+f7Y3/zmN2mHc/vtt5tjp0+fjvvvv7/Yh67+pyEg0Szj5eG2aF577bW48cYbMWnSJJx//vn45je/Ces75bjfk/ub+EWuLBs2bMADDzyAu+++G3PnzsXPfvYz863obpSPfvSjWLx4Mfiko2Tld7/7nenHH//4R1x88cVYuHAhTj311MMOPfnkk3HkkUfi4YcfdqObqtMHBD7+8Y+DX8KeSTTZ1QsuuMDs3UsnmkcccQTe8573YPny5T4YnbqQCwGJZi7USuQct0WTmE466STw0VIvvPDCIdSuv/56vOtd78JnP/vZ3r/za8emTZuGf/3rX64SpghSNHfv3p2yHQrnhRdeiH/84x+YMGGCOY68nnjiCXz4wx82v19yySVoaGjAj370I1f7q8oLRyDfotnY2GhE89FHHy3coNRynwhINPuEr7hP9kI0aTF+6Utfwuuvv44RI0b0is/YsWMxdOhQvPjii70QH3zwQaxbtw4//vGPXQX71a9+1Yjm5s2bsxJNXugeeeQRUFBZvva1rxnRtAu/qx1X5Z4T+MQnPmGeu5wvS/PEE080oklPhkpxEpBoFue85aXXXogmxZIuzJtvvhlXXXWV6fdf/vIXzJ4923yhNYWLAspCy+4rX/kKTjjhBOOi5Xd4VldX47XXXsOvf/1r8C79u9/9Lr7zne/g3HPPxde//nW8733vM1+OTXfvu9/9bmzdutWI7l//+lfceeedpq7EcsMNNxjRXLVqlWPRpDvt85//PJqbm02dX/7yl/HPf/7TtHnWWWcZ65if8/FaO3fuxOmnn276maykGtt1111nrFZeqNevX49XXnnFjPnxxx/HyJEjs6orF068wXnqqaeMi7Gtrc3w49ylG9vTTz+N733vexg0aBBaWlpM/I9eBH45r+Wep7XG8XCuabXzc96A0Grv7OzET3/6U3zyk58042Md11xzDd58800jVqNHjzaxwkRXPeduwYIF5niugT/96U/o7u425w4bNsyIEtvkXLEdPmCbJV1/+Tnr4brieOrr680a4WMjLdFMNXc814l7lmuFoun2jWFeLhCqJCkBiWYZLwwvRJN4mRzB+CXFkoUXyFmzZmHevHmgUPACzwskvz2FsU0WXoi/9a1vmZ/nzJmDuro63HfffeZ3XsR4MWSiBgsvqsuWLTMXfBZeMGtqaoz7NFmhGFA0GbNMVZK5Z9lvCrRladrPPfvss/GhD30In/vc58zF+wc/+IGJ4SYr6cbGmC/7z7boPuZYP/3pTxse2daVDSeO6Ytf/KK5EWCc+TOf+Qx27NiBJUuWINXYdu3ahaOPPtpwnzFjhplDvs+cORO8MWHhN9ozrj1//nzs2bMH73//+43IUSgpSmzzD3/4g/FEsFx55ZXmpoPzQ44TJ07Epz71KXOTkli+//3vm5sp3tAMGTIEN910E7797W9jxYoVmDJlCrZt2wZadrxhu+yyy5Cpv2+99ZYRacYkL7roItNcons23dw5EU3GyCma9FKoFCcBiWZxzlteeu2VaFLU6KJ94403zAWZcUuKI5ODGDN89dVX8eSTT+KZZ57BT37yk8PGxgspj7FEkcfwxfoYL2XclAuZ1sngwYONyFJgKbTJCl2svCj/9re/zZto8saAF3gKuZXs5GSSEsfGc2kZnXPOOeZ0MqLVc++992asri+caLnTXf6rX/3KtMOkLLqdeZOQamwUPgoSxckqt912mxEEehEs0aQgn3feeeZ3igbH+NBDD5nfaUVzjLFYzPzOOWMdl156qfmdNwycV66PZKLJuteuXWs+okVMy5zvxxxzjPkbLV/WzxuwTP2l9cdjKNrWHKaLaSbydiKaZErRvOKK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sjhksphnMrFUDDNn7DpRBESgwARSWZ2JFmUmoS3kMCSaBaKfSTgzWZMSzwJNnJoVARHImkAqC9GpOPrBwuy1fuWezXr+83ZCOuHL9bO8dU4ViYAIiEAeCaQTvlw/y2P3HFclS9MxKvcOdGI1OjnGvR6qZhEQARHIHwEnlqOTY/LXI+c1STSds3L9SAmj64jVgAimHNCVAAABSklEQVSIgM8J+FUs5Z71+cJh9ySiRTBJ6qIIiECfCPhdJBMHJ0uzT9Pt/ckSUu+Zq0UREIH8ECg2gUw2aolmftaCahEBERABESgDAhLNMphkDVEEREAERCA/BCSa+eGoWkRABERABMqAgESzDCZZQxQBERABEcgPAYlmfjiqFhEQAREQgTIgINEsg0nWEEVABERABPJDQKKZH46qRQREQAREoAwISDTLYJI1RBEQAREQgfwQkGjmh6NqEQEREAERKAMCEs0ymGQNUQREQAREID8EJJr54ahaREAEREAEyoCARLMMJllDFAEREAERyA8BiWZ+OKoWERABERCBMiAg0SyDSdYQRUAEREAE8kNAopkfjqpFBERABESgDAhINMtgkjVEERABERCB/BCQaOaHo2oRAREQAREoAwISzTKYZA1RBERABEQgPwT+H9XsmdFbV10LAAAAAElFTkSuQmCC" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="461" height="150"><figcaption>Example of modal with Teleport</figcaption></figure><p>If you try, you can see, we don&#x2019;t have a problem with the HTML semantics.</p><h3 id="reason-2-write-a-more-readable-code">Reason 2: Write a more readable code</h3><p>The second reason to use a Teleport component is to have a readable code. Indeed, in some cases, Teleport allows simplifying the code.</p><h4 id="example-alert-component">Example: Alert component</h4><p>Imagines an application where you want to display an alert message at the top of your page. The alerts can be created everywhere in your code (in the case of a form-sending error for example).</p><p>For that, you need to transport your data from one component to another component by using the store (Vuex, Pina, etc.) for example. </p><p>But with Teleport, you can have another solution. I created a simple alert component:</p><pre><code class="language-vue">&lt;template&gt;
 &lt;div class=&quot;alert&quot;&gt;
   &lt;slot&gt;&lt;/slot&gt;
 &lt;/div&gt;
&lt;/template&gt;
&lt;style scoped&gt;
.alert {
 border-radius: 5px;
 color: white;
 background: #00bfff;
 padding: 10px;
}
&lt;/style&gt;</code></pre><p>And I add the teleport component:</p><pre><code class="language-vue">template&gt;
 &lt;Teleport to=&quot;#content-alert&quot;&gt;
   &lt;div class=&quot;alert&quot;&gt;
     &lt;slot&gt;&lt;/slot&gt;
   &lt;/div&gt;
 &lt;/Teleport&gt;
&lt;/template&gt;
</code></pre><p>Now, if I add an alert to my project my alert is shown before the content:</p><pre><code class="language-vue"> &lt;div id=&quot;content-alert&quot;&gt;&lt;/div&gt;
 &lt;div&gt;
   I&apos;m the content on the website
   &lt;Alert&gt;I&apos;m an alert message !&lt;/Alert&gt;
 &lt;/div&gt;</code></pre><p>The result is:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="data:image/png;base64,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AIHyI3Bxs/Avey3oSDsFk3iDR0IGzZVGLGFNSPn52NBTBBBAAAEEshfwmg//be39Ghc88pE4c4EBJPvL8w4EEEAAAQQQQCCzAAEksxGvQAABBBBAAIFiFigzAeSxxx7TjTfeqKOOOkr9+/cv5m5yuvwEli9frttuu0233HKL3n77be27775lAuvLL7/U1VdfralTp2r69Ollok00AgEEEECg+ATSBpDRo0frkUce0RNPPKFevXrplFNO0THHHKOqVasG/79fv37F14KkM/Xp00c77rgjAaREdAs+aU5OTpkKIG7tgw8+GHwWChNAevTood13310333xzKWhySQQQQACBTAL5joAsXLhQDRo00AMPPKBzzjknOE/Tpk315JNPaq+99sp03g36+eeff67WrVurYcOGweujEkD81SkeLdh///03qJ+ZXpTqkOn1Rf15uvaX1QAyYMAATZs2Lesun3322erWrZtOOOGE4L3FXbOsG8QbEEAAAQT+IpBVAOnZs2cQQNq1a1dkRt8QOnbsqBdffFHbbrvtnwGka9euuvvuu4t8/pI8wSuvvKKXX35Zr776apEvk86hyCfNcIJ07XcAeeedd7TPPvuU9OU3+PweAbnvvvs0ZcqUDX5Pfi8szpoVuTGcAAEEEEBAWQWQY489VoMGDdL333+v0047Tb///ru6d++ujz/+WGvWrNGFF16ozTffXI8//rjGjh0rhwmPFNSqVesv1F53cNlllwVD7LvttlsQaPzvHgFp1KiRqlWrpg8//FBr167V008/rb59+wbv//HHH3XuuecGP//55591xBFH/Dk6k1rL1atX67rrrtOQIUOCkRuP6Hh656677pKvf/HFF2v8+PGqW7eufvvtt2AdhPvi6afjjz9eq1atCl7/6aef6o8//tA111yjSy65RB999JHOO+88LVmyJOif/9/OO+8cGPgc9erV09y5c4M1Fe7PlVdeqTvuuCN4ErfJpEmTtM022+itt94Krp3OIbUvRWlv6rnya78DyFVXXaVvv/1WHpFp0aKF3nzzzeCfPvLrX/L5XRN/Bl566SVdcMEFgY3t58yZoxo1aqhmzZoaNmxYYON/9+ia633vvffq/fffD17jvvoz1rx58+Azceutt6p3794aM2ZMUJNTTz1VV1xxhSpUqKAffvghqEXt2rUDc3+WbrjhBr3++uuB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" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="544" height="140"><figcaption>Result of alert with Teleport</figcaption></figure><p>If I had not used the teleport feature then I needed to transport my data with a store for example and my code would have been more complicated. </p><p>In the case, you add a new alert, the second will insert in the DOM after the first:</p><pre><code class="language-vue">&lt;div id=&quot;content-alert&quot;&gt;&lt;/div&gt;
 &lt;div&gt;
   I&apos;m the content on the website
   &lt;Alert&gt;I&apos;m an alert message !&lt;/Alert&gt;
   &lt;Alert&gt;I&apos;m a second alert message !&lt;/Alert&gt;
 &lt;/div&gt;
</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="data:image/png;base64,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/NoReBo6RC/g028fWDMCRsAIGIH4I6Afv9PDtIEtqKfhO0gex6g091OjgW9jjT+ENmMjYASMQPEmoBxGj8owuG5uD8M38zxFo3jjsdkZASNgBIxAfgmYaOSXmB1vBIyAEYhjAkVGNF555RUeeOABzjvvPJ566qk4XpKDO/WdO3fyyCOP8PDDD/Pll19y4oknHtwBhLjahAkTuOuuu1i0aBFLly4tEmOyQRgBIwBBRSMlJYWXXnqJ1157jT59+jBo0CAuuOACypYt6/374MGDDwi7/v3707VrVxONA0I3704TEhKKlGhotM8//7x3L/wT0ejVqxdHHXUUDz30UCHQtEsageJLIKSnsW7dOmrVqsVzzz3Hdddd5xGoX78+r7/+Oscee2xUiPzxxx+0aNGCpKQkr79YEQ092qJd+cknn3xAOESl0zw6CTb+oioaw4cPZ8mSJflGcu2119K9e3cGDhzonRvtNcv3gOwEI1BMCORLNHr37u2JRuvWrQs8fX2J27dvzwcffEC7du3+Fo1u3brx5JNPFrj/A9nBxx9/zEcffcQnn3xS4MsE41DgTsN0EGz8Eo2vvvqKE0444UBfPuL+5Wk888wzLFy4MOJzQh0YzTUr8GCsAyMQwwTyJRoXXngho0aN4q+//uKKK65g+/bt9OjRgx9//JG9e/cyZMgQateuzauvvsqMGTOQAGhHXqVKlf0QKY5+2223eeGHI4880hMh/VmeRp06dShfvjzff/89+/bt480332TAgAHe+YsXL+b666/3Pl+9ejXnnHPO315Q4Brs2bOHe++9lzFjxngekjwnhb6eeOIJdP1//etfzJ49m+rVq7N582Yvrq+5KDR38cUXs3v3bu/4X375hR07dnD33Xdzyy238MMPP3DDDTewZcsWb376t759+3oM1EeNGjVIS0vzcgSaz5133sljjz3m7XjFZP78+RxyyCF88cUX3rWDcQicS0HGG9hXqPFLNIYOHcr06dORB9i4cWM+//xz7/9qoebn37/WRPfAhx9+yE033eSxEftVq1ZRsWJFKleuzG+//eax0Z/lxWq9n376ab799lvvGM1V91ijRo28e2LYsGH069ePadOmeWty+eWXc8cdd1CiRAnmzZvnrUXVqlU95rqX7r//fv7zn/943LU+7733Xsg1C3XdGP4+29CNwAEnkC/R8B+Nvvhv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" class="kg-image" alt="Teleport in Vue 3" loading="lazy" width="397" height="118"><figcaption>Result with two alert</figcaption></figure><h2 id="teleport-is-a-very-cool-feature-opinionated"><strong>Teleport is a very cool feature (opinionated)</strong></h2><p>As you can see Teleport is a very cool feature! He use easier our life with the management of the DOM outside our scope component.</p><p>It&#x2019;s not the only component created with Vue3. With this version, we have some components with cool features to create our web applications. &#x1F604;</p><p>However, you need to do good use of this feature! By controlling the DOM outside to scope of your component if you abuse to use Teleport you can have side effects and it will come to hard to debug. </p><p>Moreover, this component has inconvenient because if we target an element inside on your Vue application and this element isn&#x2019;t mounted, the Teleport doesn&#x2019;t work. This problem is supposed to be solved this year. You can see more details on the <a href="https://www.youtube.com/watch?v=OrT0tHGXyqE&amp;t=751s&amp;ref=tech.jolimoi.com">roadmap video</a>.</p>]]></content:encoded></item><item><title><![CDATA[REX Luxembourg Voxxed days]]></title><description><![CDATA[<figure class="kg-card kg-image-card"><img src="https://lh4.googleusercontent.com/fPjpX4vnb_kNdDMzkp72J_2W43B0Xw4hGG11AF3zeftAxH0X1ANIHq0OqGxtKE7c2U4FFOUvp4DutjILXEoMWuzf7O_EIwJ2sZnj5RYEmaomSiXevs4BsrpWN-RO-vyizhx2K_tM4PkaxDlBOhiuxgk" class="kg-image" alt loading="lazy" width="602" height="401"></figure><p>We had the chance to participate as a speaker at the Voxxed Day Luxembourg 2023 which takes place from June 21st to June 22nd. It is a tech event to discover new concepts, and new technologies or exchange opinions and ideas on our work. I have two conferences during this</p>]]></description><link>https://tech.jolimoi.com/rex-luxembourg-voxxed-days/</link><guid isPermaLink="false">64e4643949630a03d967bf8f</guid><dc:creator><![CDATA[Kevin Besset]]></dc:creator><pubDate>Wed, 23 Aug 2023 07:43:39 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img src="https://lh4.googleusercontent.com/fPjpX4vnb_kNdDMzkp72J_2W43B0Xw4hGG11AF3zeftAxH0X1ANIHq0OqGxtKE7c2U4FFOUvp4DutjILXEoMWuzf7O_EIwJ2sZnj5RYEmaomSiXevs4BsrpWN-RO-vyizhx2K_tM4PkaxDlBOhiuxgk" class="kg-image" alt loading="lazy" width="602" height="401"></figure><p>We had the chance to participate as a speaker at the Voxxed Day Luxembourg 2023 which takes place from June 21st to June 22nd. It is a tech event to discover new concepts, and new technologies or exchange opinions and ideas on our work. I have two conferences during this event that impressed me I want to share with you:<br></p><h2 id="a-frontend-application-to-rule-them-all">A frontend application to rule them all</h2><p>The first presentation I attended was a 1-hour conference by Sylvain Dedieu, a software development engineer from Criteo. The goal of this session was feedback on his personal experience regarding structuring a complex front-end application and working with micro-frontends.<br></p><p>His need was to have 2 applications (app A &amp; app B) and navigate through the apps seamlessly for the user, giving the illusion of being on one single website but he had several conditions:</p><ul><li>be able to not be restricted to a specific version or language of a technology</li><li>to keep things simple without any super complex architecture impossible to maintain</li><li>of course, be viable in terms of performances</li><li>flexible enough to make the project evolve without having impacts across the application.</li></ul><p>To do that, Sylvain explained mainly 3 approaches :</p><h3 id="an-approach-by-libraries">An approach by libraries</h3><p>The first proposition was to use NPM to create common dependencies between the two apps. For example, having a &#x201C;layout&#x201D; external component used as a library by the 2 apps brings a common colors schema and header component across the pages. Then, the 2 applications would have a different domain: appA.example.com and appB.example.com for example and we can navigate between them by redirecting to the right subdomains delivering an almost-perfect illusion of having one single application. Using &#x201C;reverse proxy&#x201D; can also improve the illusion of having one single domain.<br></p><p>One nice thing about using NPM is that you will have its full power of versioning, so you can surely improve your libraries without risking breaking anything already on production till you didn&#x2019;t increase the version of this particular app. <br></p><p>The cons of using this approach are that we need to avoid making your dependencies take care of too much on your apps, or it&#x2019;s going to be very hard to maintain. Also, it is possible to have some applications that are never updated so when we want to migrate, it is going to be super hard. Finally, the illusion is great but it is not a real SPA since we have some HTTP redirection between the multiple subdomains, so we don&#x2019;t fully use the power of frontend frameworks such as Vue or React.<br></p><h3 id="the-micro-front-end-approach">The micro-front-end approach</h3><p>The second approach is quite similar but here, instead of using NPM as our bundler, we will create real &#x201C;sub-apps&#x201D; for each part of our main application. Every sub-app points to its own port and is injected into the main application using a tooling bundle such as Module Federation that came with Webpack 5. Then, depending on the URL of the main app, it is able to know which sub-app it needs to load.</p><p>Contrary to the NPM approach, here it is a real SPA in the end, it is not an illusion. Also, the main app will always get the latest version of the sub-apps, allowing it to upgrade the entire application at the same time.</p><p>However, it is a little bit more complex from the first approach because we are working with multiple app that needs to be running at the same time, and handling correctly the port injection.<br></p><h3 id="the-mono-repo-approach">The mono-repo approach</h3><p>Finally, Sylvain explained that it is possible to build one single project that will have all the sub-apps inside, and everything is handled by one single package.json file. It will help to handle cross libraries and also to run all the apps together without having trouble going on the sub-app X, pulling the changes, re-running it, etc&#x2026; Here one commit is across all the apps so you are sure to be always up-to-date in local. It works well with the 2 previous approach<br></p><p>At the end of the conference, Sylvain talked about Nx, which is a tool that allows us to have visual feedback on our micro-frontend architecture. It creates a graph where you can see all your micro-frontends together and how they communicate with each other. Also, he showed us that it is possible to allow/disallow some sub-apps to be used by others. For example, a sub-app &#x201C;UI library&#x201D; for your project could be pulled by all other services but a &#x201C;Page A&#x201D; sub-app should never be pulled by &#x201C;UI library&#x201D;, it has no sense. So by doing that, Nx can bring you warnings and tell you that you are doing something that seems to be a bad pattern.<br></p><h2 id="feedback-on-bitdev">Feedback on bit.dev</h2><p>Then, I attended to the 15-minute quickie of Lucille Moise, a front-end developer from Serli who wanted to share feedback regarding bit.dev.<br></p><p>She had a situation where she used multiple UI libraries (like Ant design and Material UI) in their application which created several incoherences, sometimes on the same page! So she needed to find a solution to have a seamless experience across the entire application without forgetting the advantages of using a UI library: to create and design an app in a short amount of time.<br></p><p>The answer to that was to create a component library and so, she started to write a tier list of things she would need. Mostly, she wants it to be fast, very collaborative with easy-to-use components, and also easy to work inside the library. To do that she wants to be well-documented and easy to maintain. Two solutions came to her mind: Storybook or bit.dev. She then decided to iterate with bit.dev to see if it would match well the need (because she already knew and used Storybook in the past).<br></p><p>Bit.dev is an open-source toolchain for the development of composable software. It allows devs to create components as you usually would and then import them in bit.dev to have visual documentation available for everyone. Within, we can create pages to explain when to use a specific component, where to use it, etc. Bit.dev also gives us the possibility to visualize the dependencies among your components and create trees of dependencies to find maybe very heavy libraries used only for 1% of its possibilities and also only in one single component in our UI library.<br></p><p>Finally, bit.dev gives us the possibility to publish our documentation in order to give access to the &#x201C;non-dev&#x201D; users like designers, and product managers for example.<br></p><p>She used it now inside their team and could see the benefits of having bit.dev:</p><ul><li>The app was released in time and ran perfectly in production</li><li>Newcomers didn&#x2019;t struggle to work with it</li><li>She saw that bit.dev is constantly evolving<br></li></ul><p>For her, it was important to anticipate the need and analyze your components in order to be able to structure it. You can help with bit.dev online examples, and even to bit.dev directly, they are super reactive and with good help.<br></p><h2 id="conclusion">Conclusion</h2><p>Overall, it was a very good conference, the chance to discuss personally with all involved people during the 2 days was super interesting.</p>]]></content:encoded></item><item><title><![CDATA[Taking people with you: 4 things that helped me as a new manager]]></title><description><![CDATA[Excerpt: It could be daunting to start the path of engineering manager. With this article, I am sharing what I learned from the book “Taking People With You” by David Novak.]]></description><link>https://tech.jolimoi.com/taking-people-with-you-4-things-that-helped-me-as-a-new-manager/</link><guid isPermaLink="false">6488790249630a03d967be1a</guid><dc:creator><![CDATA[Bastien Bonard]]></dc:creator><pubDate>Wed, 09 Aug 2023 08:23:50 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2023/06/image-1.png" medium="image"/><content:encoded><![CDATA[<h2 id="preamble">Preamble</h2><img src="https://tech.jolimoi.com/content/images/2023/06/image-1.png" alt="Taking people with you: 4 things that helped me as a new manager"><p>I always had an appetite for accompanying people in their technical projects. To me, the interaction we have with the technical tools is fascinating (much more than the technical tools themselves). So naturally, after strengthening some pure programming abilities, I decided to take on the &#x201C;Engineering Manager&#x201D; challenge. Not as a logical promotion after years of service, but as a turning point in my career. And this was a real decision to become an effective one. Learning and working my way up to the proper mindset and skill set.</p><p>One of the many books I devoured to improve my understanding of this job was &#x201C;Taking People With You&#x201D; by David Novak. And this one stood off!</p><p>So much so that I wanted to share what had an impact on my progression as a fresh manager.</p><h2 id="1-being-your-best-self">#1 Being your best self</h2><p>Ok, this one is probably not quite exclusive to the Engineering Manager profession. But being your best self, or the best version of yourself is particularly important when it comes to this job.</p><p>People will turn to you, either actively or passively. Just look at how you are, and what you do, and it will impact them. After all, <em>you are a manager,</em> and it makes you at least an implicit reference. So you truly need to embody your values, be as sharp as you can be, and live out every piece of wisdom you will ever want to share. Then you can understand what it means, what can be challenging, and where the struggles are while being a doable proof.</p><p>So this piece of advice helps to have a positive impact on the team.</p><h2 id="2-people-do-things-even-they-didn%E2%80%99t-know-they-could-do">#2 People Do Things Even They Didn&#x2019;t Know They Could Do</h2><p>This piece of advice resonates a lot with another key concept I hold dear which is &#x201C;naive optimism&#x201D;. We don&#x2019;t necessarily plan to do &#x201C;amazing things&#x201D;, we plan to do regular things, and they turn out to be amazing. But for this to truly work, you have to shun all the possibilities it can go wrong, and not focus on the fact you cannot do it. Try and learn. You&#x2019;ll probably fail, but if you succeed, what a victory! And interestingly, it is exactly how we learn to walk. We have no experience, no muscles, no muscle memory, nothing. On paper, it is a lost cause, and a robotic engineer will say it to you: walking is a marvelous feat. But we get there eventually! After a lot of falls, and more perseverance.</p><p>It is hard to have this naive optimism for ourselves. But if we do, and if we manage to help others, it can lead to interesting results, and drastically open up the possibilities.</p><h2 id="3-being-an-avid-learner">#3 Being an avid learner</h2><p>I considered myself pretty solid when it comes to learning and oh boy I was wrong. The way I saw learning was always very academic, structured, planned, and so on.</p><p>But here, knowledge is not acquired, it is devoured. There is a certain chaos in that process, which leaves room for unexpected opportunities. Everything is a source of learning, everything and all the time. It fires in all directions, on every topic. And instead of properly framing one topic and learning all its details, you have a learning trend about a concept. The trend brings you more connections, often outside the box (because you get rid of the frame).</p><p>And being an avid learner becomes more than a piece of advice, it&#x2019;s a concept that shapes how you see the world and everything around you.<br>It is again not tied to this job and is globally handy (especially when you are starting).</p><h2 id="4-recognition">#4 Recognition</h2><p>This incentive straightforwardly echoed my fresh experience. I find it much easier to work around mistakes, failures, and problems. Easier to have the feedback, easier to spot, and easier to address. Whereas it feels tricky to find all the wins, as there are a lot of silent ones. But then the conveyed message is all twisted (focusing on negative things), and it could greatly impact the motivation of the team.</p><p>Getting to see the extra mile done here and there, managing to notice the further care given on tasks, and then simply giving some attention and praise about it. I think it is both trickier and more rewarding. Not only do you build a positive feedback loop, but you also reinforce a nice work atmosphere. Oh, and it does feel good for everyone to bring recognition to the table! Which is a good source of energy and motivation for everyone.</p><h2 id="to-sum-it-up">To sum it up</h2><p>While knowing there are a lot more key drives and concepts, I think it&#x2019;s easier to get on track with these 4 when starting the path of Engineering Manager. If one was to stand out, I would say &#x201C;being an avid learner&#x201D; as it could continually impact you at a ground level.</p>]]></content:encoded></item><item><title><![CDATA[What's sketchnoting?]]></title><description><![CDATA[🎨 Today I would like to talk to you about sketchnoting :  a method of writing synthesis and illustrations.]]></description><link>https://tech.jolimoi.com/whats-sketchnoting-2/</link><guid isPermaLink="false">64be3f7c49630a03d967bf22</guid><dc:creator><![CDATA[Mélissandre pozo]]></dc:creator><pubDate>Wed, 26 Jul 2023 13:52:41 GMT</pubDate><media:content url="https://tech.jolimoi.com/content/images/2023/07/kelly-sikkema-Hl3LUdyKRic-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://tech.jolimoi.com/content/images/2023/07/kelly-sikkema-Hl3LUdyKRic-unsplash.jpg" alt="What&apos;s sketchnoting?"><p><em>Have you ever written a report without much conviction, drowned in hundreds of lines and sentences, each one more formal than the previous one. Tried to make an idea or a concept understood without much success through incomprehensible notes?</em></p><p>Sketchnoting is a restitution method belonging to a group of techniques called &quot;Graphic Facilitation&quot;. Very close to the mind mapping method, sketchnoting offers a wider choice of results by mixing sentences, words, and illustrations. Its particularity is that it uses several senses such as hearing, sight, and touch, which makes it very interesting to practice and accessible to a large number of people. The iconographic vocabulary is very personal and you can develop and enrich it as you practice sketching.</p><p>&#x201C;Sketchnoting, also commonly referred to as visual notetaking, is the creative and graphic process through which an individual can record their thoughts with the use of <a href="https://en.wikipedia.org/wiki/Illustration?ref=tech.jolimoi.com"><strong>illustrations</strong></a>, <a href="https://en.wikipedia.org/wiki/Symbol?ref=tech.jolimoi.com"><strong>symbols</strong></a>, <a href="https://en.wikipedia.org/wiki/Structure?ref=tech.jolimoi.com"><strong>structures</strong></a>, and texts.&#x201D; Wikipedia</p><p>Originally used in &quot;live&quot;: during meetings, interviews, conferences, this method can be used after taking notes leaving the sketch artist the possibility to pose his plan.</p><p><strong>Why is it so great to use this method in companies?</strong><br>First of all, anyone can do it. You won&apos;t be asked to be a Picasso! The idea of the Sketchnote is to allow everyone to convey ideas effectively through drawings and text.</p><p>The basics are a few geometric shapes, which you&apos;ll see a little further on in this article... and that&apos;s it!</p><h2 id="this-also-allows-you-to"><strong>This also allows you to :</strong></h2><ul><li>Make reports much more digestible and visual to all the teams.</li><li>Make concepts or ideas more easily understood, by imaging the thought process.</li><li>Deliver a very personal interpretation during the restitution.</li></ul><h2 id="and-now-to-your-pencils">And now, to your pencils!</h2><p><strong>For 1 person, you&apos;ll need the following items:</strong></p><p>&#x1F4D1; Blank sheets of paper, &#x270D;&#xFE0F;Pens, &#x1F58D;&#xFE0F; Multi-coloured felt-tip pens</p><p>You will also be able to do your sketch on <strong>procreate</strong> available at the moment only on Ipad. <br>You will also need to draw graphic elements such as squares, triangles, circles, lines and points. Remember, you are not asked to be an artist, it is the understanding of the idea that counts.<br><br>1 - Start by <strong>prioritizing your text</strong>, sorting out what seems important to you or not. If you are taking notes live, try to divide up the speech you are listening so that you have a plan in mind.<br><br>2 - Write your title to structure your summary, using <strong>a banner</strong> for example.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/07/9a34d402edf8e228933b2bc5e8849a02.png" class="kg-image" alt="What&apos;s sketchnoting?" loading="lazy" width="2000" height="1124" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/07/9a34d402edf8e228933b2bc5e8849a02.png 600w, https://tech.jolimoi.com/content/images/size/w1000/2023/07/9a34d402edf8e228933b2bc5e8849a02.png 1000w, https://tech.jolimoi.com/content/images/size/w1600/2023/07/9a34d402edf8e228933b2bc5e8849a02.png 1600w, https://tech.jolimoi.com/content/images/2023/07/9a34d402edf8e228933b2bc5e8849a02.png 2049w" sizes="(min-width: 720px) 720px"></figure><p>3 - Link ideas together using <strong>linking elements</strong>. You can also separate them thanks to separation elements.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/07/connectors-dividers-sketchnotes.jpg" class="kg-image" alt="What&apos;s sketchnoting?" loading="lazy" width="1600" height="503" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/07/connectors-dividers-sketchnotes.jpg 600w, https://tech.jolimoi.com/content/images/size/w1000/2023/07/connectors-dividers-sketchnotes.jpg 1000w, https://tech.jolimoi.com/content/images/2023/07/connectors-dividers-sketchnotes.jpg 1600w" sizes="(min-width: 720px) 720px"></figure><p>4 - Add illustrations to make the drawing easier to understand! Don&apos;t panic, you don&apos;t have to be Picasso to make a sketch.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/07/Sketchnote_Bildersprache_klein.jpg" class="kg-image" alt="What&apos;s sketchnoting?" loading="lazy" width="1417" height="664" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/07/Sketchnote_Bildersprache_klein.jpg 600w, https://tech.jolimoi.com/content/images/size/w1000/2023/07/Sketchnote_Bildersprache_klein.jpg 1000w, https://tech.jolimoi.com/content/images/2023/07/Sketchnote_Bildersprache_klein.jpg 1417w" sizes="(min-width: 720px) 720px"></figure><p>5 - Finally, don&apos;t forget to play with different colours to highlight important elements.</p><figure class="kg-card kg-image-card"><img src="https://tech.jolimoi.com/content/images/2023/07/with-Mike-Rohde.jpg" class="kg-image" alt="What&apos;s sketchnoting?" loading="lazy" width="1000" height="986" srcset="https://tech.jolimoi.com/content/images/size/w600/2023/07/with-Mike-Rohde.jpg 600w, https://tech.jolimoi.com/content/images/2023/07/with-Mike-Rohde.jpg 1000w" sizes="(min-width: 720px) 720px"></figure><p>So you will have understood that this method makes it possible to :</p><ul><li>Text synthesize</li><li>Prioritize information</li><li>Sort information</li><li>Develop your creativity</li><li>Memorize items up to +6.5 times the normal value.</li></ul><p>Now you have all the keys in your hands! Now all you have to do is get started on your first sketchnoting...and now, to your pencils! &#x2764;&#xFE0F;</p><p><br></p><p><br></p>]]></content:encoded></item></channel></rss>