<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fanny</title>
    <description>The latest articles on DEV Community by Fanny (@fannyvieira).</description>
    <link>https://dev.to/fannyvieira</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F18418%2Ffe283e09-a96a-4c23-85c9-b2f38968377b.jpg</url>
      <title>DEV Community: Fanny</title>
      <link>https://dev.to/fannyvieira</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fannyvieira"/>
    <language>en</language>
    <item>
      <title>Planning  and designing projects effectively</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Thu, 19 Nov 2020 16:11:18 +0000</pubDate>
      <link>https://dev.to/fannyvieira/planning-and-designing-projects-effectively-2fe9</link>
      <guid>https://dev.to/fannyvieira/planning-and-designing-projects-effectively-2fe9</guid>
      <description>&lt;p&gt;As a way of saving this for a personal consultation, avoiding frequent mistakes and helping people who are not used to exercising the project planning and management muscle, I've decided to write this post. This year, I related to many teams that did not have a programming background, because of that I was the owner and responsible for directing many projects, so I decided to write some of the lessons I learned from experiences I had. These lessons helped me to come up with better ideas, set better the project schedule and consequently succeed in implementing them.&lt;/p&gt;

&lt;p&gt;When we have a team of engineers, these project planning responsibilities fall on product managers, product owners and so on, our job is to implement and have insights on how to make the process better. But in any case, having a good plan is essential for good engineering and good design, especially when you are dealing with complex or large projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a document
&lt;/h2&gt;

&lt;p&gt;So you had an idea started writing a document you shared with your colleagues, but you didn't get the feedback you expected, because your document might not highlight what you wanted or the way you wanted it?&lt;/p&gt;

&lt;p&gt;You ask yourself, what is useful to have in a document so that you can convince and draw the reader's attention to the most important points? And you don't know what to do... I hope to answer this question for you like amazing people answered it for me&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;People need to have a clear view of what you intend to do, do it at the top of the document, so they will have this in top of mind while reading your entire text.&lt;/p&gt;

&lt;p&gt;You also want to make it clear what things within that scope you want to cover, that is, it is useful to limit and explicitly write down what the project does not propose to do, it is probably also interesting to explain the reasons for not covering these other things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;It is important to demonstrate which problems you want to solve, so that people understand how relevant and urgent this problem is. It may be interesting to use some metrics or analyze what your team priorities are at that moment. Make it clear if what you intend to do will solve all or part of the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design
&lt;/h2&gt;

&lt;p&gt;You don't want to go too far in discussing the solution design. It is useful to provide high-level design, so that it helps you and the people who will work on the project, you should stop writing when you feel that the details you are providing will not make it easier for you to build your solution.&lt;/p&gt;

&lt;p&gt;Be extremely open to hearing feedback on this part (as well as the others), also make it clear what options you have considered and why you have not followed them. This avoids repetition of discussions and will likely cause you to focus on the feedbacks you need most.&lt;/p&gt;

&lt;h2&gt;
  
  
  Risks
&lt;/h2&gt;

&lt;p&gt;While there are things that are beyond our control, it is important that you list and try to find out what can go wrong. After all, if the project is a success, the team wins. Take some time to reduce the chances of failure.&lt;br&gt;
From time to time, double check to make sure your assumptions are still valid. Ask your partners for help. And have an alternative, if things don't go well.&lt;/p&gt;

&lt;p&gt;Finally? After writing and discussing, &lt;em&gt;stop&lt;/em&gt; thinking about risks or failures. Focus on solving your problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Milestones
&lt;/h2&gt;

&lt;p&gt;Milestones are very important for people to understand how things are going or how long they will take. So write a series of milestones for the job, so they'll understand it easily. &lt;/p&gt;

&lt;h2&gt;
  
  
  Estimative
&lt;/h2&gt;

&lt;p&gt;The estimate is certainly difficult to get right; many projects do not work for that.In most cases it is useful to talk to someone who has done something even remotely similar. Tell them what you are going to do and ask for their impression.&lt;/p&gt;

&lt;h2&gt;
  
  
  People
&lt;/h2&gt;

&lt;p&gt;Record who were the people you requested feedback from and validated your idea. This is useful if you are stuck or want to align if you are heading in the right direction. Also list what that person does will probably be interesting for you to remember when and why you need them.&lt;/p&gt;

&lt;p&gt;Certainly planning and defining a document like this requires hard work, probably it will be difficult to get it right the first few times, but as you train, get more practice and help as things will work out better. I hope I have been useful in some way.&lt;/p&gt;

</description>
      <category>management</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Dear, Code Reviewer</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Mon, 25 May 2020 14:37:15 +0000</pubDate>
      <link>https://dev.to/fannyvieira/dear-code-reviewer-930</link>
      <guid>https://dev.to/fannyvieira/dear-code-reviewer-930</guid>
      <description>&lt;p&gt;Recently, a friend started to discuss with me about some approaches used when developers review his code. He seemed angry about some comments so I decided to do this post, expressing my opinion about things that he said and I frequently see and read in blogs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The trampoline
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l396SbpG7USk2iAN2/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l396SbpG7USk2iAN2/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, you are developing a feature, you put your code for review, the reviewer made some comments, you complete the suggestions, the reviewers accepted your changes (The LOOKS GOOD moment) and you push your code. But ... let's talk about the real world.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OpCsaegy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.makeameme.org/created/looks-good-to-sxlux9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OpCsaegy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.makeameme.org/created/looks-good-to-sxlux9.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You develop your feature, and you're very excited.. you place your code for review, the review started ... The reviewers made some comments and suggestions some trivial and others not so easy neither clear. You started to implement the suggestions, ask for clarification and talk about why you didn't made some things. Your updates are good but looking to your new code, there are some things that the reviewers found that they don’t like about your first code. You again made the suggested changes, but new problems are found and this cycle repeats ...&lt;/p&gt;

&lt;p&gt;The big problem here is that in each iteration, new problems are addressed, causing an infinite loop in the review, and you might be thinking: "Ok, sometimes the code needs to be improved, it's impossible to avoid those things" although there are a million of reasons for this happens, I think that some common factors to this happen is when the team does not have good guidelines and patterns to review the code or when the comments made by the reviewers are so complicated to understand, and the author cannot achieve the goal.&lt;/p&gt;

&lt;p&gt;The whole process needs to be clear for both sides, in the mind of the reviewer needs to be clear the list of things that are required to finish the task, and for the author what things he needs to do, to complete the task.&lt;/p&gt;

&lt;h3&gt;
  
  
  The nitpick comments
&lt;/h3&gt;

&lt;p&gt;I don't know if you passed through for this situation, but usually, if your code has four spaces instead of two or if you don't have a blank line at the end of the file you'll receive: &lt;code&gt;NIT: {comment}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What do you think about this? These tasks seem things easily replaced for an automated checker like &lt;a href="https://github.com/prettier/prettier"&gt;Prettier&lt;/a&gt; and &lt;a href="https://github.com/eslint/eslint"&gt;Eslint&lt;/a&gt;. If my team pass-through for this situation, may I should ask myself, Do we have good style guidelines? and Are we providing some automated solution?&lt;/p&gt;

&lt;h3&gt;
  
  
  The divergent reviews
&lt;/h3&gt;

&lt;p&gt;Continuing the previous reasoning, if my team doesn't have good style guidelines and a more methodic method to review, probably different reviewers will have different opinions if all the team doesn't know what the priorities, or the best practices, how do they can reach consensus?&lt;/p&gt;

&lt;h3&gt;
  
  
  Without time, bro
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mBcS7kCi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/proxy/gI1KQVZx1vVCPF1Iu-dVuFIZ6RxebJrE4gBlzrBvvkEKSFcLIrNZK51gP5bp4YJlQDF7Lc0df6h8Rv6AILqGcbVRZdXMUTD41BKUy8odLqP4JvtRBMrQGC125Fe_zB8ZOs-UsbPAnESjHkFby5_cwyJMsyDbFqINeWM" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mBcS7kCi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/proxy/gI1KQVZx1vVCPF1Iu-dVuFIZ6RxebJrE4gBlzrBvvkEKSFcLIrNZK51gP5bp4YJlQDF7Lc0df6h8Rv6AILqGcbVRZdXMUTD41BKUy8odLqP4JvtRBMrQGC125Fe_zB8ZOs-UsbPAnESjHkFby5_cwyJMsyDbFqINeWM" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes you see yourself leaving the review for a time that you can look well and your mind is in the right place. Maybe the review is large or the architecture is complex or is it a breaking change, right?&lt;/p&gt;

&lt;p&gt;Right, but nobody wants to be blocked, if the code is not in production, what the value it has?&lt;/p&gt;

&lt;p&gt;Of course, there are many reasons to cause this, but if you are an author try to split your features into small pieces, and when you open the review make sure the purpose is really clear. And if you are a reviewer ensure that you have a piece of your time to review code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reposting, because the previous had few errors&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Don't overabstract the things</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Mon, 13 Apr 2020 23:08:19 +0000</pubDate>
      <link>https://dev.to/fannyvieira/don-t-overabstract-the-things-3dig</link>
      <guid>https://dev.to/fannyvieira/don-t-overabstract-the-things-3dig</guid>
      <description>&lt;p&gt;What if I? should we move this? should we recreate this component?&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;A few days ago, I started to build some components to a large app, and I didn't can avoid a whirl of thoughts, about what is the better approach to build my components, or what is the better way to improve the existents and why not reuse the old ones?&lt;/p&gt;

&lt;p&gt;But I forgot one thing, we ALWAYS need a starter point.&lt;/p&gt;

&lt;p&gt;So, my coworker said something like: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Slow down, Fanny. We don't need overabstract the things."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The painful abstraction
&lt;/h2&gt;

&lt;p&gt;Each abstraction adds benefits and costs. When we don't have a deep knowledge about the things, probably we'll pay a cost using an approach for a problem that don't exists, we cannot enjoy properly of the benefits. And this is essential to use abstractions effectively.&lt;/p&gt;

&lt;p&gt;I was passing for a problem that is very common among developers: &lt;strong&gt;The premature abstraction.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Being premature
&lt;/h2&gt;

&lt;p&gt;Some people talked with me about premature things, but I didn't have a complete understand about. But here's what I found in this situation, you are premature, when you add abstractions in your code, before you really understand the problem, and the possible scenarios.&lt;/p&gt;

&lt;p&gt;My point is not say that abstract things is bad, on the contrary, but if I would follow this direction, probably I would leave the things hard to maintain, or unwieldly.&lt;/p&gt;

&lt;p&gt;The goal of have an abstraction is to provide an easy way to use things, or fix bugs, and even thought understand the code without the need to look for specific details of implementations.&lt;/p&gt;

&lt;p&gt;So, I'll leave here my &lt;em&gt;advice&lt;/em&gt;: Sometimes the best thing that you need to do, is delay your abstraction, and start with a simple approach, after this, you probably will gain a better idea of what you need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://news.ycombinator.com/item?id=19237592"&gt;HackerNews - The cost of abstraction&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=4anAwXYqLG8"&gt;Minimal Surface API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.deconstructconf.com/2019/dan-abramov-the-wet-codebase"&gt;The Wet Codebase&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
      <category>codequality</category>
    </item>
    <item>
      <title>React's weaknesses</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Sat, 29 Feb 2020 12:35:45 +0000</pubDate>
      <link>https://dev.to/fannyvieira/react-s-weaknesses-3b5h</link>
      <guid>https://dev.to/fannyvieira/react-s-weaknesses-3b5h</guid>
      <description>&lt;p&gt;In the last years, React has placed a lot of effort in improve many of it apis to be more easier and friendly to new comers. This happened with hooks, for example one of the motivations was because using classes components is so confused and complex for beginners, beyond the fact that until this point react had problems with reuse stateful logic. Although this exists, one really topic controversial and commented is about the state management in React, and the resistance generated in many developers to learn or use redux, because it is necessary to change a lot of files, and know many abstractions, yeah, we have the &lt;code&gt;&amp;lt;Context&amp;gt;&lt;/code&gt; alternative, but do you think that this API is enough to complex things or global state management? or is it better to resort to redux?&lt;/p&gt;

&lt;p&gt;My point is that I miss a more structured solution on this topic in React, Last days I was reading reddit and one of the maintaners of redux, it argued that with the library we would be able to have consistent architectural patterns, debugging capabilities and etc. And I agree with him, probably using the Context API and hooks, we'll suffering a lit bit to achieve these things.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>react</category>
      <category>redux</category>
      <category>help</category>
    </item>
    <item>
      <title>Lessons taked while i'm riding my bike</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Sat, 08 Feb 2020 00:07:46 +0000</pubDate>
      <link>https://dev.to/fannyvieira/lessons-taked-while-i-m-riding-my-bike-2al1</link>
      <guid>https://dev.to/fannyvieira/lessons-taked-while-i-m-riding-my-bike-2al1</guid>
      <description>&lt;p&gt;Usually i try to cover some topic related to programming that I'm studying,  but today i'll talk about a habit that i really enjoy: riding a bike, and the benefits that i figure out while i'm enjoying my daily walk.&lt;/p&gt;

&lt;p&gt;For me riding a bike it's not just to sit and move my legs, it's a moment that i can reflect about the things that I planned for my day, and some things that i passed on the week, and is also about focus on the way that i'll cycling.&lt;/p&gt;

&lt;p&gt;So, let's deep dive on my lessons.&lt;/p&gt;

&lt;h2&gt;
  
  
  You're are on the control
&lt;/h2&gt;

&lt;p&gt;When you ride a bike, you're in the control, you need to concentrate your mind in the activity, to don't fall, not lost your target, your direction. And in our life it's not different, if you aims to achieve something you need to put your focus and effort in that, and don't allow that the other things blocks you, or distance you from your goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  One step at time
&lt;/h2&gt;

&lt;p&gt;It's important have a step at time, make baby steps for the things, start of the basics and it goes progressively increasing your rhythmic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try to skip the obstacles
&lt;/h2&gt;

&lt;p&gt;When you're riding, sometimes you have obstacles, but if you like your backside(haha), and you want to keep your bike whole, you need to avoid the obstacles, when is possible. In the life, it's not different, you need to develop the ability to ignore some things for make possible a progress in other areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  You have your time
&lt;/h2&gt;

&lt;p&gt;We humans, have a  habit to compare ourselves with the others, and it's difficult to us understand that each person have your rhythmic, your conditions and your history, when i'm riding, i see people driving in different velocities, and i learned that it's ok, many people will pass in front of me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make stops
&lt;/h2&gt;

&lt;p&gt;For you don't make tired, you need to have moments of relaxing, when you is in a transit you is obligate to stop sometimes to allows that the cars pass, and this is very cool because you have a time to reenergise yourself.&lt;/p&gt;

&lt;p&gt;And that's it, do you have any lesson that you learned with a bike too? Please, share with me! &amp;lt;3&lt;/p&gt;

</description>
      <category>bike</category>
      <category>personal</category>
      <category>life</category>
      <category>career</category>
    </item>
    <item>
      <title>The beauty of Functional Programming</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Thu, 26 Dec 2019 21:00:24 +0000</pubDate>
      <link>https://dev.to/fannyvieira/the-beauty-of-functional-programming-32ck</link>
      <guid>https://dev.to/fannyvieira/the-beauty-of-functional-programming-32ck</guid>
      <description>&lt;p&gt;There are many ways to make a program, probably you already made your program like a serie of commands, this is what we called of "imperative programming" or maybe you do your program keeping things in objects and interacting with them sending messages back and forward, this is "object oriented programming", but today i'll talk about Functional Programming, like the others mentionated, functional programming is a coding style, this is not about put or not &lt;code&gt;;&lt;/code&gt; or put  &lt;code&gt;{}&lt;/code&gt; after or below the expressions, but it's how we can instruct the program to make the things, in a technical way this is a "programming paradigm". So why you should care about this?&lt;/p&gt;

&lt;h3&gt;
  
  
  Fun Fun Functions ✨
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/XOXdQszYm4I3m/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/XOXdQszYm4I3m/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we talk about the world of functional programming, everything are functions. And the concept is too similar the math concept, when we study at school, the teacher says something like: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A function is a special relationship between values: Each of its input values gives back exactly one output value&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;from &lt;a href="https://www.mathsisfun.com/sets/function.html" rel="noopener noreferrer"&gt;mathisfun&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This definition is really important because give us the basis of our programs, called &lt;strong&gt;pure functions&lt;/strong&gt;, pure functions are functions that only depends of its inputs, they don't look for anything else outside of your world, expect the arguments that you passed through, and only returns the output, they don't affect oher part of world. For example, see these functions, you can say what's wrong with the first?&lt;/p&gt;

&lt;p&gt;First version ❌&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getMyAge&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`I'm &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; years old.`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;getMyAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="nf"&gt;getMyAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second Version ✅&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getMyAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`I'm &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; years old.`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;getMyAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;getMyAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first case, the function is looking for a variable outside of your scope, changing the world of some way, in this case the output, the ideal is only return the value and if as you noticed, if we call the function, with same argument(even there's no argument), we get it a different value. In a pure function this is not happen.&lt;br&gt;
Now, you have a basic idea of good things provided by functional programming, but we have more, check it out below our abilities 💪.&lt;/p&gt;
&lt;h2&gt;
  
  
  Side Effects 🌊
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;side effect&lt;/strong&gt; is any interaction with our outside world that occurs during the calculations, that don't happen using pure functions, and our code, can be more predictale, because our results only depends its inputs, if we know what the function looks like, and which inputs it receives, you can predict the result..&lt;/p&gt;
&lt;h2&gt;
  
  
  Mutability 🐺
&lt;/h2&gt;

&lt;p&gt;Mutability is about things changeable, here in func. programming the mutability is discouranged. When we have immutable data, its state cannot change after you created, if you need change something, you need create a new value. &lt;/p&gt;

&lt;p&gt;Mutable example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;changeFirstElem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lose yourself to dance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;daftPunkPopSongs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Instant Crush&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Get Lucky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;One More Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;changeFirstElem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;daftPunkPopSongs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Immutable example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;changeFirstElem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modifiedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lose yourself to dance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;modifiedArray&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;daftPunkPopSongs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Instant Crush&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Get Lucky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;One More Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modifiedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;changeFirstElem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;daftPunkPopSongs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is awesome, because we make the things more safer, its harder do introduce bugs in our code, also means that is easier to test/debug our code. It's because the one thing that we need to know is about the output, follow the params, and if the output is wrong, we're sure that the problem is our function and not because a random interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursion 🥞
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F506%2F1%2AW1MmCSV4cJUnT7TuANWIOw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F506%2F1%2AW1MmCSV4cJUnT7TuANWIOw.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recursion is a technique, in that we can solve a problem in small pieces, this help us to avoid some side effects when we use interactions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;myCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;myCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For me, the recursion makes a code more declarative, more readable and cleaner, although in many scenarios i prefer using iterative way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The super heroes of Functional Programming 🧚‍♀️
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F785%2F1%2AyD7P1I36G1jTProLQwEXxA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F785%2F1%2AyD7P1I36G1jTProLQwEXxA.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beyond the recursion, we have tree functions that help us to manipulate the data they are &lt;strong&gt;map-filter-reducer&lt;/strong&gt;. In JS, functions also treated as values, since that, we can pass it a parameter to other functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map&lt;/strong&gt;, given a collection of data, you can pass a function to transform each item.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doubles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//[2, 4, 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filter&lt;/strong&gt; receives a collection of data, and you can pass a conditional function that returns a subset of collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isGreaterThanOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//[2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, &lt;strong&gt;Reduce&lt;/strong&gt;, given a collection of data you can reduce to a single value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mySum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion 💃
&lt;/h2&gt;

&lt;p&gt;I'm beginning on the study of functional programming, and these things motivates me to start and keep seeing many resources, obviously, functional programming has weakness, but now that's not the point. If you need other resources i'll left some below, enjoy and have-fun!&lt;/p&gt;

&lt;h3&gt;
  
  
  Books
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://hackernoon.com/understanding-functional-programming-with-javascript-41eb3fa8c2a" rel="noopener noreferrer"&gt;Hackernoon - Understanding Functional Programming&lt;/a&gt;&lt;br&gt;
&lt;a href="https://mostly-adequate.gitbooks.io/mostly-adequate-guide/content/" rel="noopener noreferrer"&gt;Professor Frisby's Mostly Adequate Guide to Functional Programming&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jcouyang.gitbooks.io/functional-javascript/content/en/index.html" rel="noopener noreferrer"&gt;Functional JavaScript Mini Book by Jichao Ouyang&lt;/a&gt;&lt;br&gt;
&lt;a href="https://haskellcamargo.gitbooks.io/pragmatic-functional-javascript/" rel="noopener noreferrer"&gt;Pragmatic Function Javascript online book&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Talks
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=qtsbZarFzm8" rel="noopener noreferrer"&gt;Anjana Vankil - Functional Programming: What? Why? How?&lt;/a&gt;&lt;em&gt;One of my favourites&lt;/em&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=Wo0qiGPSV-s" rel="noopener noreferrer"&gt;Anjana Vankil - Immutable data structures for functional JS&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=BMUiFMZr7vk&amp;amp;list=PL0zVEGEvSaeEd9hlmCXrk5yUyqUag-n84" rel="noopener noreferrer"&gt;Fun Fun Function Series&lt;/a&gt;&lt;/p&gt;

</description>
      <category>functional</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>My Data Visualization Resources</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Wed, 18 Dec 2019 12:55:44 +0000</pubDate>
      <link>https://dev.to/fannyvieira/my-data-visualization-resources-408f</link>
      <guid>https://dev.to/fannyvieira/my-data-visualization-resources-408f</guid>
      <description>&lt;p&gt;Last months, i decided to go deep to learn a little bit about data viz, more specifically about charts. In almost everything that i do, i have inspirations, today i want to share my resources about the principles and how to make good charts. I have used or gone through each of these personally.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/fanny"&gt;
        fanny
      &lt;/a&gt; / &lt;a href="https://github.com/fanny/data-vis"&gt;
        data-vis
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      My collection of resources and other useful information for my personal studies of data visualization
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Data Visualization 📊
&lt;/h1&gt;
&lt;p&gt;My collection of resources and other useful information for my personal studies of data visualization&lt;/p&gt;
&lt;h2&gt;
Content 📝
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#miscellaneous-black_joker"&gt;Miscellaneous 🃏&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#visual-encoding-eyes"&gt;Visual encoding &amp;amp;&amp;amp; Visual Vocabulary 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#blogs-computer"&gt;Blogs &amp;amp;&amp;amp; favourite sites 💻&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#podcasts-headphones"&gt;Podcasts 🎧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#react-libraries-%EF%B8%8F"&gt;React Libraries ⚛&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#courses-mortar_board"&gt;Courses 🎓&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#books-book"&gt;Books 📖&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#creative-coding-inspirations-art"&gt;Creative Coding Inspirations 🎨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/fanny/data-vis/master/#"&gt;Referencies&lt;/a&gt; &lt;em&gt;COMING SOON&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Miscellaneous 🃏
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://visualizationuniverse.com" rel="nofollow"&gt;Visualization universe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://datavizforall.org/chart-design.html" rel="nofollow"&gt;DataViz for all&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/chart/interactive/docs" rel="nofollow"&gt;Google Charts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/glosophy/CatoDataVizGuidelines/blob/master/PocketStyleBook.pdf"&gt;Cato Institute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1F1gm5QLXh3USC8ZFx_M9TXYxmD-X5JLDD0oJATRTuIE/edit#gid=1679646668" rel="nofollow"&gt;Nightingale Resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://data.london.gov.uk/blog/city-intelligence-data-design-guidelines/" rel="nofollow"&gt;City intelligence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://microsoft.github.io/chart-parts/" rel="nofollow"&gt;Microsoft Chart-Parts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Visual Encoding 👀
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.targetprocess.com/articles/visual-encoding/" rel="nofollow"&gt;Target process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ibm.com/design/v1/language/experience/data-visualization" rel="nofollow"&gt;IBM Data Vis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://datavizcatalogue.com/index.html" rel="nofollow"&gt;Data Vis Catalogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://journalismcourses.org/courses/DE0618/Visual-vocabulary.pdf" rel="nofollow"&gt;Visual Vocabulary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Design Systems&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://material.io/design/communication/data-visualization.html" rel="nofollow"&gt;Google Material Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://polaris.shopify.com/design/data-visualizations#navigation" rel="nofollow"&gt;Shopify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lightningdesignsystem.com/guidelines/charts/" rel="nofollow"&gt;SalesForce&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.carbondesignsystem.com/data-visualization/chart-types/" rel="nofollow"&gt;Carbon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spectrum.adobe.com/" rel="nofollow"&gt;Adobe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://adele.uxpin.com/" rel="nofollow"&gt;Adele&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Blogs 💻
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://eagereyes.org/" rel="nofollow"&gt;Eagereyes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://flowingdata.com/" rel="nofollow"&gt;Flowingdata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://informationisbeautiful.net/" rel="nofollow"&gt;Information is beautiful&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lisacharlotterost.de/" rel="nofollow"&gt;Lisa Rost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pudding.cool/" rel="nofollow"&gt;Pudding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fivethirtyeight.com/" rel="nofollow"&gt;FiveThirtyeight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://truth-and-beauty.net/" rel="nofollow"&gt;Truth and beauty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.vis4.net/blog/" rel="nofollow"&gt;vis4net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://idl.cs.washington.edu/papers/" rel="nofollow"&gt;UW interactive data lab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.datavisualizationsociety.com/resources" rel="nofollow"&gt;Data Visualization Society&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.data-to-viz.com/caveats.html" rel="nofollow"&gt;Data to Viz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
React Libraries ⚛️
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/recharts/recharts"&gt;Recharts&lt;/a&gt; &lt;em&gt;Based on d3&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/uber/react-vis"&gt;Uber datavis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/FormidableLabs/victory"&gt;Victory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nivo.rocks/" rel="nofollow"&gt;Nivo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vx-demo.now.sh/" rel="nofollow"&gt;VX&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Creative Coding Inspirations 🎨
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.openprocessing.org/" rel="nofollow"&gt;OpenProcessing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://inspiring.online/" rel="nofollow"&gt;Inspiring Online&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devart.withgoogle.com/" rel="nofollow"&gt;DevArt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://experiments.withgoogle.com/collection/chrome" rel="nofollow"&gt;Google Experiments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Courses 🎓
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.pluralsight.com/courses/data-visualization-best-practices" rel="nofollow"&gt;Pluralsight - Data Visualization: Best Practices&lt;/a&gt; &lt;code&gt;$$&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Books 📖
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Storytelling-Data-Visualization-Business-Professionals/dp/1119002257" rel="nofollow"&gt;Storytelling with data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/fanny/data-vis"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>dataviz</category>
      <category>react</category>
      <category>charts</category>
      <category>resources</category>
    </item>
    <item>
      <title>Usando Scrapy para obter metadados das músicas dos Parcels através do Genius</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Sat, 31 Aug 2019 21:55:01 +0000</pubDate>
      <link>https://dev.to/opendevufcg/usando-scrapy-para-obter-metadados-das-musicas-dos-parcels-atraves-do-genius-1dhj</link>
      <guid>https://dev.to/opendevufcg/usando-scrapy-para-obter-metadados-das-musicas-dos-parcels-atraves-do-genius-1dhj</guid>
      <description>&lt;p&gt;Você já quis obter dados de um serviço que não disponibiliza uma API? Se você faz Computação na UFCG, provavelmente já escutou alguém falando do bot de matrícula. Já perguntou como ele funciona? Pois bem, no post de hoje você aprenderá como é possível fazer essas coisinhas e poderá usar sua criatividade para brincar e explorar ainda mais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mr. Robot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0IyiADcZ3Ecjrn5m/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0IyiADcZ3Ecjrn5m/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um &lt;strong&gt;web crawler&lt;/strong&gt; pode ser definido como um script ou programa que é utilizado para acessar um website, extrair conteúdo e descobrir páginas relacionadas ao mesmo, repetindo o processo até que não existam mais páginas a ser pesquisadas.&lt;br&gt;
Eles são muito importantes, pois as engines de busca os utilizam para retornar resultados eficientes; devido a isso, frequentemente, algumas pessoas se referem a eles como bots da internet. De uma forma superficial, você pode pensar no crawler como um carinha que faz requisições para as páginas que ele encontra e, à medida que percorre essas páginas, faz o parse do seu HTML.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pré-Requisitos
&lt;/h2&gt;

&lt;p&gt;Para conseguir reproduzir o que faremos nesse tutorial você precisará ter o Python 3 configurado. Uma alternativa é usar o &lt;a href="https://www.digitalocean.com/community/tutorial_series/how-to-install-and-set-up-a-local-programming-environment-for-python-3"&gt;virtualenv&lt;/a&gt;, que possibilita a criação de um ambiente de desenvolvimento isolado.&lt;/p&gt;

&lt;p&gt;Além do Python 3, faremos uso do &lt;a href="https://scrapy.org/"&gt;&lt;strong&gt;Scrapy&lt;/strong&gt;&lt;/a&gt;, um framework que possui as ferramentas necessárias para &lt;strong&gt;extrair&lt;/strong&gt; dados de websites, &lt;strong&gt;processar&lt;/strong&gt; os que você queira e &lt;strong&gt;armazená-los&lt;/strong&gt; na estrutura de seu interesse. Apesar de ser possível construir um crawler usando módulos fornecidos pelo próprio Python, à medida que o seu projeto cresce, pode se tornar complicado gerenciar a execução do seu robôzinho, por isso faremos uso desse framework. Entretanto, caso você tenha interesse em conhecer outras alternativas, deixarei links nas referências.&lt;/p&gt;

&lt;p&gt;Para instalá-lo, utilize o índice de pacotes do Python(&lt;a href="https://pypi.org/"&gt;&lt;code&gt;PyPI&lt;/code&gt;&lt;/a&gt;), através do seguinte comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install Scrapy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Feito isso, podemos dar início à nossa implementação.&lt;/p&gt;
&lt;h2&gt;
  
  
  Além das letras
&lt;/h2&gt;

&lt;p&gt;Se você usa o Spotify, já viu que vez ou outra em algumas músicas são exibidas as letras e algumas informações interessantes que são extraídas do &lt;a href="https://genius.com/"&gt;&lt;strong&gt;Genius&lt;/strong&gt;&lt;/a&gt;. Motivada em obter essas informações de uma banda que eu conheci recentemente, chamada &lt;a href="https://open.spotify.com/artist/3oKRxpszQKUjjaHz388fVA"&gt;&lt;strong&gt;Parcels&lt;/strong&gt;&lt;/a&gt; (inclusive, fica aqui a sugestão: se você gosta de &lt;em&gt;Daft Punk&lt;/em&gt;, provavelmente vai curtir a música deles), decidi construir esse crawler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UqcNMU9w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://spotifysupport.freetls.fastly.net/article-gallery/articles2/android/android_behind_the_lyrics.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UqcNMU9w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://spotifysupport.freetls.fastly.net/article-gallery/articles2/android/android_behind_the_lyrics.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A primeira coisa que um crawler precisa é de um ponto inicial, também chamado de &lt;strong&gt;seed&lt;/strong&gt;, que será usado para iniciar a extração dos conteúdos. No nosso caso, esse ponto será a página da banda no Genius (&lt;a href="https://genius.com/artists/Parcels"&gt;essa aqui&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Uma vez que temos isso, podemos iniciar a construção do nosso robôzinho. Crie um arquivo python chamado &lt;code&gt;genius.py&lt;/code&gt;, que possui o seguinte conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;scrapy&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GeniusSpider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scrapy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Spider&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"genius"&lt;/span&gt;
    &lt;span class="n"&gt;start_urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'https://genius.com/artists/Parcels'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Primeiro, importamos o &lt;strong&gt;Scrapy&lt;/strong&gt; para ter acesso às funcionalidades que esse módulo fornece. Em seguida, criamos um classe chamada &lt;code&gt;GeniusSpider&lt;/code&gt;, baseada na &lt;code&gt;Spider&lt;/code&gt; do Scrapy; é ela que define quais métodos estamos hábeis a usar, métodos estes que poderão nos auxiliar durante a execução do crawler. Por fim, definimos o nome do spider como &lt;strong&gt;genius&lt;/strong&gt; e o nosso &lt;em&gt;seed&lt;/em&gt; como sendo a página dos Parcels.&lt;/p&gt;

&lt;p&gt;Diferentemente do que fazemos para executar scripts em Python, usaremos o comando que o próprio Scrapy provê por meio da sua CLI:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;scrapy runspider genius&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/J5vyIVNU6PI2QVVMm7/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/J5vyIVNU6PI2QVVMm7/source.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Certo, temos várias letrinhas bonitinhas e outras nem tanto, mas o que tudo isso quer dizer?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O Scrapy carregou e configurou o que precisava para iniciar;&lt;/li&gt;
&lt;li&gt;Requisitou a url que definimos no &lt;code&gt;start_urls&lt;/code&gt;, e baixou o seu conteúdo;&lt;/li&gt;
&lt;li&gt;Repassou esse conteúdo para um método parse. Como não o tínhamos criado, nada aconteceu e ele finalizou a execução.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Extraindo metadados
&lt;/h2&gt;

&lt;p&gt;O próximo passo é definir &lt;strong&gt;como&lt;/strong&gt; o Scrapy deve extrair o conteúdo: fazemos isso definindo o método &lt;strong&gt;parse&lt;/strong&gt;. Nesse passo, é importante que você entenda como estão organizados os elementos da sua página, pois será essencial para transmitir ao crawler quais locais ele deve &lt;strong&gt;raspar&lt;/strong&gt; quando extrair a página.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rcVbpnbk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/YJ9G6sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rcVbpnbk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/YJ9G6sg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Analisando a imagem acima, você pode ver que à sua direita existe uma listagem de cards com as músicas populares que, quando clicados, nos levam ao conteúdo que queremos. Dessa forma, esse deve ser o local de onde nosso crawler irá extrair os links.&lt;/p&gt;

&lt;p&gt;O Scrapy extrai o conteúdo através de seletores, que são "padrões" ou "modelos" que casam com os elementos de uma árvore do documento e portanto podem ser usados para selecionar os nós de um documento HTML. Para conseguir fazer isso, o Scrapy fornece duas formas: através do Xpath e através de seletores CSS; usaremos os seletores CSS por questão de simplicidade.&lt;/p&gt;

&lt;p&gt;Usando o inspetor do meu browser para analisar quais os nós que contêm esse link e então formar o nosso seletor, consegui notar que o elemento que contém essa lista de cards é uma div. Veja no GIF:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mini_card_grid-song"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="https://i.giphy.com/media/IfgHqsThQhDxkhy6C5/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/IfgHqsThQhDxkhy6C5/source.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sendo assim, podemos informar ao &lt;strong&gt;Scrapy&lt;/strong&gt; que ele deve obter algo como:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;div.mini_clard_grid-song a::attr(href)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Isso indica que queremos os links que são filhos de um elemento da classe &lt;code&gt;mini_card_grid-song&lt;/code&gt;, por isso o &lt;code&gt;.&lt;/code&gt; (como em CSS). Além disso, adicionamos esse trecho &lt;code&gt;::attr(href)&lt;/code&gt; depois da tag &lt;code&gt;a&lt;/code&gt;, porque se definíssemos o padrão apenas com a tag teríamos todo o nó HTML, e não apenas a url.&lt;/p&gt;

&lt;p&gt;Para entender melhor sobre os seletores CSS, veja &lt;a href="https://docs.scrapy.org/en/latest/topics/selectors.html"&gt;esse link&lt;/a&gt; da documentação.&lt;/p&gt;

&lt;p&gt;Assim, podemos construir nosso método:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;songs_urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'div.mini_card_grid-song a::attr(href)'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;song_url&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;songs_urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;scrapy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;song_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_lyrics_page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;O método é composto por um parâmetro &lt;strong&gt;response&lt;/strong&gt;, que indica o conteúdo obtido após o crawler ter requisitado nossa url inicial. Feito isso, temos as urls das músicas sendo obtidas a partir do nosso seletor; essa lista de urls que o crawler requisitará é chamada de &lt;strong&gt;frontier&lt;/strong&gt;. É importante ressaltar que usamos o &lt;code&gt;getAll()&lt;/code&gt;, porque queremos extrair &lt;strong&gt;todos&lt;/strong&gt; os seletores que casarem com o padrão que passamos, mas às vezes estamos interessados apenas na primeira ocorrência e podemos fazer uso do &lt;code&gt;get()&lt;/code&gt;. Uma vez que temos as urls, fazemos as requisições, passando a url e uma &lt;strong&gt;callback&lt;/strong&gt;, que é uma função que será executada após o crawler fazer download da url que passamos.&lt;/p&gt;

&lt;p&gt;Ótimo, conseguimos alcançar as páginas das nossas músicas, mas depois que chegamos nelas, o que faremos? Seguimos um processo muito parecido com o anterior, diferindo apenas que, ao invés de tentar extrair links, poderemos extrair as informações desejadas. Do passo anterior, vemos que o método que será executado após ser consultada a página da música é o &lt;code&gt;parse_lyrics_page&lt;/code&gt;, então adicione esse trecho ao seu arquivo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_lyrics_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'div.song_body-lyrics h2::text'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;song_metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'div.rich_text_formatting p::text'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;artists&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'span.metadata_unit-info a::text'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;lyric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'div.lyrics p::text'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;annotations_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'a::attr(annotation-fragment)'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;'artists'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;artists&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;'lyric'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lyric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;'metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;song_metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;'snippet_lyric'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s"&gt;'annotations'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;annotations_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_annotations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;annotations_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_annotations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;annotations_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;annotation_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;annotations_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urljoin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;annotation_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;scrapy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_annotation_page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'item'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Muita coisa, né? Mas vamos por partes, como diria Jack.&lt;/p&gt;

&lt;p&gt;Para extração das informações básicas como os artistas, a letra, o título e os metadados, não temos nenhuma novidade em relação ao que fizemos na extração dos links, já que só precisamos fornecer o seletor e ele irá obter a informação.&lt;/p&gt;

&lt;p&gt;No entanto, as anotações seguem um comportamento diferente. Olhando a página, você verá que os elementos que deveriam conter as informações de anotações das músicas contém apenas um identificador, que redireciona para outra página que abriga o conteúdo delas. Então, o que estamos fazendo é: &lt;/p&gt;

&lt;p&gt;Se existem anotações, obtenha seus ids e, para cada id obtido, concatene a nossa url inicial: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;urljoin(response.url, annotation_id)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E, em seguida, fazemos uma requisição para cada um deles. Mas espere, essa requisição tem algo que ainda não vimos antes: um parâmetro chamado &lt;code&gt;meta&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/a5viI92PAF89q/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/a5viI92PAF89q/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;meta&lt;/code&gt; é a forma que o Scrapy provê para que consigamos nos comunicar entre uma página e outra. Então, o que estamos querendo dizer é que toda vez que ele consultar as páginas das anotações, leve consigo as informações que já extraímos dessa. Isso será útil para unirmos os dois objetos e retornamos os resultados.&lt;/p&gt;

&lt;p&gt;Agora que você está na página de anotações, encontre os seletores das anotações e retorne o resultado, e pronto, você terá feito o crawler. Deve ficar algo como mostrado no trecho abaixo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_annotation_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;snippet_lyric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meta[property='og:title']::attr(content)"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;annotations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meta[property='og:description']::attr(content)"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;getall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'item'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'snippet_lyric'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;snippet_lyric&lt;/span&gt;
        &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'annotations'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;annotations&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Caso não existam anotações, ele já retornará o resultado, que é o objeto com as informações que obtivemos na primeira página. Para salvar o que coletamos em um &lt;code&gt;json&lt;/code&gt;, usamos o comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;scrapy runspider genius -o parcels-lyrics.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Você terá algo com:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; É possível salvar o dado em outros formatos, como csv, dê uma olhada na &lt;a href="https://docs.scrapy.org/en/latest/topics/feed-exports.html#topics-feed-exports"&gt;documentação&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;E é isso, você construiu o crawler! :hoo-ray:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/PSKAppO2LH56w/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/PSKAppO2LH56w/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações finais
&lt;/h2&gt;

&lt;p&gt;Até aqui você aprendeu os conceitos básicos para construir um crawler. À medida que seu projeto expandir, você precisará lidar com outras coisas, como &lt;em&gt;politeness policies&lt;/em&gt;, porque pense: se fizermos muitas requisições para um site, podemos sobrecarregá-lo e torná-lo indisponível por algum tempo para outros usuários. Leitura de sitemaps também são importantes para garantir que o crawler consiga obter efetivamente certos links que o website acredita ser essenciais, além de várias outras técnicas.&lt;/p&gt;

&lt;p&gt;Entretanto, agora que você já sabe o básico, me conta nos comentários alguma ideia que você pensa em construir! E se tiver qualquer dúvida ou sugestão, fique à vontade para adicionar comentários neste post ou trocar uma ideia comigo fora dele (minhas redes sociais estão mapeadas no meu perfil).&lt;/p&gt;

&lt;p&gt;E se quiser estar por dentro do que eu tô fazendo e escutando (música é realmente uma das minhas paixões além de Computação), me segue no &lt;a href="https://open.spotify.com/user/anotherfanny"&gt;Spotify&lt;/a&gt; ou &lt;a href="https://www.last.fm/pt/user/Fannyvieira25"&gt;Last.fm&lt;/a&gt; e &lt;a href="https://github.com/fanny"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tutoriais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.scrapy.org/en/latest/intro/overview.html"&gt;Documentacão do Scrapy&lt;/a&gt;;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.datacamp.com/community/tutorials/making-web-crawlers-scrapy-python"&gt;Fazendo web crawlers em Python - Inglês&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@marlessonsantana/utilizando-o-scrapy-do-python-para-monitoramento-em-sites-de-not%C3%ADcias-web-crawler-ebdf7f1e4966"&gt;Utilizando o Scrapy do Python para monitoramento em sites de notícias - PTBR&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Livros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com.br/Learning-Scrapy-Dimitris-Kouzis-Loukas/dp/1784399787"&gt;Learning Scrapy&lt;/a&gt;; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com/Web-Scraping-Python-Collecting-Modern/dp/1491910291/ref=as_li_ss_tl?ie=UTF8&amp;amp;qid=1469961194&amp;amp;sr=8-1&amp;amp;keywords=web+scraping+with+python&amp;amp;linkCode=sl1&amp;amp;tag=scraping06-20&amp;amp;linkId=eda03663399eeff90133094d677e4cd4"&gt;Web Scraping with Python&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Obrigada
&lt;/h2&gt;

&lt;p&gt;Muito obrigada pela leitura! Fique atento: em breve, teremos novos artigos de contribuidores do OpenDevUFCG aqui no dev.to. Acompanhe o OpenDevUFCG no &lt;a href="https://www.twitter.com/OpenDevUFCG/"&gt;Twitter&lt;/a&gt;, no &lt;a href="https://www.instagram.com/OpenDevUFCG/"&gt;Instagram&lt;/a&gt; e, claro, no &lt;a href="https://www.github.com/OpenDevUFCG/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>crawling</category>
      <category>music</category>
      <category>ptbr</category>
      <category>scrapy</category>
    </item>
    <item>
      <title>What i've learned contributing for firefox dev tools</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Sat, 22 Jun 2019 03:18:47 +0000</pubDate>
      <link>https://dev.to/fannyvieira/what-i-ve-learned-contributing-for-firefox-dev-tools-2i7n</link>
      <guid>https://dev.to/fannyvieira/what-i-ve-learned-contributing-for-firefox-dev-tools-2i7n</guid>
      <description>&lt;p&gt;It's very common when we join in a community, we feel that don't be capable, or that don't have knowledge enough to fix a problem. Mainly, when it is Firefox, that is a gigantic community, i also passed through this, and i will tell you how i got over.&lt;/p&gt;

&lt;h1&gt;
  
  
  Don't be afraid
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff44maxlye1tdudavr4gd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff44maxlye1tdudavr4gd.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beginning to read and try to understand the project, naturally, there were many snippets that I didn't understand, but there were anothers, that is very similar to my university projects, see &lt;a href="https://github.com/mozilla/gecko-dev/blob/master/devtools/client/webconsole/components/FilterBar.js" rel="noopener noreferrer"&gt;this component&lt;/a&gt; of dev tools project:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createFactory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/shared/vendor/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/shared/vendor/react-dom-factories&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/shared/vendor/react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getAllFilters&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/selectors/filters&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getFilteredMessagesCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/selectors/messages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getAllUi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/selectors/ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/actions/index&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;l10n&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/utils/messages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PluralForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/shared/plural-form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;FILTERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FILTERBAR_DISPLAY_MODES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../constants&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FilterButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/components/FilterButton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FilterCheckbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/webconsole/components/FilterCheckbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SearchBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/shared/components/SearchBox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lazyRequireGetter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PropTypes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtools/client/shared/vendor/react-prop-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FilterBar&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;propTypes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;persistLogs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidePersistLogsCheckbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;showContentMessages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hideShowContentMessagesCheckbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;filteredMessagesCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;closeButtonVisible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;closeSplitConsole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;oneOf&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FILTERBAR_DISPLAY_MODES&lt;/span&gt;&lt;span class="p"&gt;)]).&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;defaultProps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;hidePersistLogsCheckbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hideShowContentMessagesCheckbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClickMessagesClear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClickMessagesClear&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onSearchBoxChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onSearchBoxChange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChangePersistToggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChangePersistToggle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChangeShowContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChangeShowContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderFiltersConfigBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderFiltersConfigBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maybeUpdateLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maybeUpdateLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resizeObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResizeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maybeUpdateLayout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filterInputMinWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapperNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.devtools-searchbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filterInputMinWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getComputedStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterInput&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;min-width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// If the min-width of the filter input isn't set, or is set in a different unit&lt;/span&gt;
      &lt;span class="c1"&gt;// than px.&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;min-width of the filter input couldn't be retrieved.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maybeUpdateLayout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resizeObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapperNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;shouldComponentUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;persistLogs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;showContentMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;filteredMessagesCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;closeButtonVisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;persistLogs&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;persistLogs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showContentMessages&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;showContentMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filteredMessagesCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt;
        &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filteredMessagesCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closeButtonVisible&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;closeButtonVisible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayMode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;componentWillUnmount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resizeObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * Update the boolean state that informs where the filter buttons should be rendered.
   * If the filter buttons are rendered inline with the filter input and the filter
   * input width is reduced below a threshold, the filter buttons are rendered on a new
   * row. When the filter buttons are on a separate row and the filter input grows
   * wide enough to display the filter buttons without dropping below the threshold,
   * the filter buttons are rendered inline.
   */&lt;/span&gt;
  &lt;span class="nf"&gt;maybeUpdateLayout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapperNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.devtools-searchbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filterInputWidth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filterInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;FILTERBAR_DISPLAY_MODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WIDE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterInputWidth&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filterInputMinWidth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterBarDisplayModeSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FILTERBAR_DISPLAY_MODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NARROW&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;FILTERBAR_DISPLAY_MODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NARROW&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterButtonsToolbar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapperNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.webconsole-filterbar-secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buttonMargin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterButtonsToolbarWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterButtonsToolbar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;buttonMargin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterInputWidth&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filterInputMinWidth&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;filterButtonsToolbarWidth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterBarDisplayModeSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FILTERBAR_DISPLAY_MODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WIDE&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, i thought, "Ok, when i don't understand something in a project that i developed with my university colleagues, i try understand, searching or asking to them, why i dont make the same here?"&lt;/p&gt;

&lt;p&gt;Initially, i was very ashamed of asking to someone(who knows me, knows that i very ashamed, fortunately i'm working on this in last days haha), but as i became aware of developer interactions with the community, I saw how much each one is always willing to teach how each thing is done and help you deal with some problem.&lt;/p&gt;

&lt;p&gt;And so I started to get involved, I went to download the project and set up, and i had many problems, the majority i got resolve looking the issues reported and resolved by community, but  there was one, that i can't remember, that i couldn't. I had to send a message in firefox chat and in few minutes, a developer answered me and i got fix the problem(Thanks to &lt;a href="https://twitter.com/nicolaschevobbe" rel="noopener noreferrer"&gt;Nicholas Chevobbe&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;And it was so that i finally got set up the project in my machine, then, don't be afraid of ask for help, when you feel very lost in a thing, surely, there will be someone willing to help you.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;important&lt;/strong&gt; part that I forgot to mention is that in order to set things up on my machine, I first read &lt;a href="https://docs.firefox-dev.tools/"&gt;this documentation&lt;/a&gt;. And i follow the instructions, it's very complete both explains the configuration and their workflow, code patterns etc&lt;/p&gt;

&lt;h1&gt;
  
  
  First things first
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famubkcvrxe1zo6iotpn0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famubkcvrxe1zo6iotpn0.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once i had set up the project, i was very excited to start developing, after all, i was almost achieving realize my dream of contribute to firefox!!&lt;/p&gt;

&lt;p&gt;One more time, i was a little confuse, then what should i do? I asked to the guy who helped me, as i could start to contribute. Who has a little experience with open source, knows that the majority of communities have some issues labeled as "Good First Issue", so what he recommended for me was look two links:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://codetribute.mozilla.org/projects/devtools?tag%3Dgood-first-bug" rel="noopener noreferrer"&gt;CodeTribute Good First Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugs.firefox-dev.tools/?easy&amp;amp;tool=all"&gt;Firefox Dev Tools Bugs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, i read one problem, &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1421342" rel="noopener noreferrer"&gt;this&lt;/a&gt;, I thought, "HERE IS MY FIRST PROBLEM!", I, as well as the mentor, we underestimate the problem, when reopening the discussion, the maintaners realized that it was not so simple, I had to talk to the network team, change some files that are not so intuitive for beginners, which made me look for others problems&lt;/p&gt;

&lt;p&gt;The second that i found was &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1457111" rel="noopener noreferrer"&gt;this&lt;/a&gt;. In short, when we had a link tag, we needed to show an option to copy the link from that tag. Previously, we needed to copy the entire tag and manually extract the link. If you read the topic, I initially understood the problem in a different way, i wanted to use regex, because I did not know it included an html tag. But then a mentor went there and explained what really should be done, and he even suggested a tool to debug and better visualize what I was doing and that starts the next topic.&lt;/p&gt;

&lt;p&gt;(As you noticed, i fail many times, but fortunately always there was someone who helped me, so do not be afraid to try !!)&lt;/p&gt;

&lt;h1&gt;
  
  
  Use tools to your favor &amp;amp; debug
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3apjy50gqqrbab8djll2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3apjy50gqqrbab8djll2.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As i said before, the documentation explains very well each module, for example, when i needed modified some thing in console, i went directly in &lt;a href="https://github.com/mozilla/gecko-dev/tree/master/devtools/client/webconsole" rel="noopener noreferrer"&gt;webconsole directory&lt;/a&gt; and i tried to find a code relationed with the issue description.&lt;/p&gt;

&lt;p&gt;To help me debug the code of the browser, i used the &lt;a href="https://developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox" rel="noopener noreferrer"&gt;tool&lt;/a&gt; quoted earlier, it's very important that you use it, because we are accustomed to do to analyze a web development project looking at the browser console, but what happens if we are developing the browser console?&lt;/p&gt;

&lt;p&gt;We can not see through the console, the code of the browser console itself, so we use it, and it is so indispensable in our development.&lt;/p&gt;

&lt;p&gt;Also, to complement the documentation studies, I found &lt;a href="https://developer.mozilla.org/en-US/docs/Tools" rel="noopener noreferrer"&gt;this link&lt;/a&gt; is quite interesting, because it gives an explanation of some internal things of these tools .&lt;/p&gt;

&lt;p&gt;Basically I analyzed the code using this browser tool box tool, and looking at the doc along with that link, and sometimes when I did not really find the link of the thing I needed, I would ask someone else, then once again DO NOT FEEL FEAR!!!&lt;/p&gt;

&lt;p&gt;Once you've done that, you'll already have the knowledge to submit your first pr (or what they call it, your patch) in the documentation, explain everything right, how you assign it to a reviewer, how to commit. It's worth mentioning that they use a different git system, it's the mercurial one, but it's very similar to the way things are done, so if you know git, you'll be able to unroll.&lt;/p&gt;

&lt;p&gt;One of the coolest parts when I submitted my first pr and it was accepted was to be recognized in the chat, I was so happy, so happy that I even took print of that moment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0wv0o3e4aov8x4wx1yb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0wv0o3e4aov8x4wx1yb.png" alt="Captura de tela_2019-03-23_11-04-14"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition, almost every week, they post on their blog the update of the week, including the work of contributors, and my name appeared on the page, twice, people, I was very happy !!!!!!!!!!!!!!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.nightly.mozilla.org/2019/03/15/these-weeks-in-firefox-issue-55/" rel="noopener noreferrer"&gt;Week 1&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.nightly.mozilla.org/2019/04/05/these-weeks-in-firefox-issue-56/" rel="noopener noreferrer"&gt;Week 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So once again, do not be afraid to contribute to the firefox community, I overcame my fear and shame, and I felt very accomplished, and not only that, be sure that you will be very well recognized for your work, the community is very receptive and welcoming, so I leave here my experience and suggestion as an excellent community to contribute.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>firefox</category>
      <category>mozilla</category>
      <category>contributors</category>
    </item>
    <item>
      <title>How to copy props in react dev tools</title>
      <dc:creator>Fanny</dc:creator>
      <pubDate>Thu, 16 May 2019 23:25:16 +0000</pubDate>
      <link>https://dev.to/fannyvieira/how-to-copy-props-in-react-dev-tools-7d7</link>
      <guid>https://dev.to/fannyvieira/how-to-copy-props-in-react-dev-tools-7d7</guid>
      <description>&lt;p&gt;Today, while I was working on a bug, I found myself needing to copy a props of a React component, so I realized that the react dev tools did not have this functionality, after some searches, i found the solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwoydhob89pw6gq2i3dg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwoydhob89pw6gq2i3dg.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;EDIT: react dev tools has a &lt;a href="https://dev.to/karataev/comment/apgk"&gt;pretty simple solution&lt;/a&gt;, thanks to Eugene&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en" rel="noopener noreferrer"&gt;ReactDevTools&lt;/a&gt; in Browser
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1awq2w7io4hez587dhq.png"&gt;
&lt;/li&gt;
&lt;li&gt;Select the component that contains the props, in that you need copy
(when you make this, the browser will be create a variable for save the component that you clicked, generally the name is $r)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7tfeeqslqeo1a22ox2p.png"&gt;
&lt;/li&gt;
&lt;li&gt;Open the console, and save the prop in another variable
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43q8y8tkghpx0vb8tsex.png"&gt;
&lt;/li&gt;
&lt;li&gt;Use the copy method and "don't worry, be happy! :D" as me.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3m85a28il922ytyez5k4.png"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cheers! 😗 😗 ❤️&lt;/p&gt;

</description>
      <category>todayisearched</category>
      <category>todayilearned</category>
      <category>reactdevtools</category>
      <category>react</category>
    </item>
  </channel>
</rss>
