So we're finally at the point. We're going to deliver the gas to end users in this particular presentation We'll go through the various types of end users. So finally, we've gathered it processed it Transported it may or may not have stored it. We were finally going to get to the burner tip So we are at the distribution point that is where the gas is distributed to multiple end users I've mentioned a couple of times the Term LDC is local distribution company. These are your actual gas companies Their primary operations distribute low-pressure gas We mentioned that the transmission pipeline system is operating anywhere from 200 to 1500 pounds per square inch You can't have that type of pressure coming into your home for your hot water heater. So Distribution companies literally drop that pressure down. You can see here at the residential level It's cut down to four point. Excuse me four to six ounces per square inch. There are commercial Customers as well industrials and then of course electric utilities operation of the LDCs. They also perform a transportation Service in several states the industry is somewhat deregulated. That is there are end users Who do not have to buy natural gas from the gas company. They can actually buy it from third-party suppliers But the gas company for LDC performs a transportation function where they receive the gas from the transmission pipeline and Deliver it to these particular end users. So the end users have their own transportation on the LDC system It's what's known as open access that is other parties than the utility themselves can ship the gas there And as I mentioned previously these end users can buy their gas from third-party non utility suppliers Here's the breakdown of the total delivered cost of natural gas a lot of people often wonder You know when they see their gas bill how much of that the producer is getting how much is the utility getting? And you can see here that the single largest cost of delivered natural gas to the burner tip is the distribution company For their services commodity portion represents slightly more than a third of the total delivered cost and you do have the services of the Transmission and storage companies as well One point that I do like to emphasize is that gas companies are not allowed to make profit on the actual price of natural gas So for instance they buy gas at three dollars and fifty cents per MMB to you They can only charge you three dollars and fifty cents per MMB to you It's strictly what's known as a pass-through cost where they make their money is on the services Required to get the natural gas delivered to you and even those rates have to be Approved by their respective public utility commissions in each state There's often a mistake that people's one natural gas prices go up and their heating bills go up that it is a function of The gas company trying to make additional profit on them in times of high demand. That is not the case Typical gas meter that you might see outside of your house or outside of a building Talk about the various types of end users here is a skyline. This just happens to be the city of Denver And users very large group is electric generation the primary Subgroup there is the utility electrical generators or UEGs. They are regulated Producers of electricity then we have the non utility electric generators. These are independent power producers They have built power plant as an investment and are not regulated by public utility commissions Another subgroup or the co-generators. These are companies that actually generate electricity and steam and the steam is sold as an energy commodity in four, you know industrial processes and Within electrical generation, we have simple cycle generators. These are gas turbines again A turbine is nothing more than a jet engine has a similar type of fan blades And it's using natural gas as the fuel and it's in spinning the blades There is the shaft connected to magnets which spin within a magneto a copper housing that creates the current We also then have steam turbines steam is generated in a boiler and The steam is projected at fan blades Which are spun then and in turn drive the magneto, which creates the current More efficient types of generators that combine cycle. These are gas and steam turbines combined So you have a combination of the first two types You're going to have a gas turbine which is using a natural gas as a fuel, but the exhaust gas Coming off of that turbine is then run through a boiler And the heat from the exhaust gas then makes additional steam and then you drive a steam turbine So it's one of the most efficient uses of natural gas as a fuel is the combined cycle generation In co-generation you are running a gas turbine to produce electricity But you're also running a steam boiler where you're selling steam as an actual commodity This is a diagram that I showed you earlier. I like it not only because it's animated But because it's it's very simplistic and as I mentioned before the arrow on the left shows a fuel source coming in It does not matter what that fuel source is as long as that fuel fuel source can produce heat To produce steam the steam again driving the turbine, which is the blue and white spinning area the shaft tied to it You know to the right there is the copper housing the magneto Which has polar opposite magnets tied to that shaft and as they spin they create current The steam is then recirculated through a cooling tower Once it's cooled down it recirculates back through the boiler and the process starts all over again So this is a steam-driven electric turbine system There's a picture of electric turbine fan blades courtesy of General Electric. They're one of the world's largest producers of turbine electric generators I Show these pictures so that if you're out and about you'll recognize the types of power plants You've already seen the photograph to the left with the large cooling stacks represent a nuclear power plant, but on the right This is a coal plant this distinguishing features there are the very tall stacks as opposed to shorter stacks for natural gas Because of the emissions from a coal plant they put out a tremendous amount of hydrogen sulfide gas As well as the actual particulate matter it's almost you know, it's a dust and so it's got to be Elevated to where it does not stay in the particular area another distinguishing feature on the plant there You'll see a long conveyor belt moving from left to right. That's where the coal was brought up and put into the crushers So when you see these features, you'll know that is a coal plant as opposed to a natural gas fire plant Now the category of end users these are industrial end users petrochemical refiners In addition to using natural gas liquids, they actually run their plants on natural gas And so it's used as part of that process as well They can be used in paper production Your steel foundries and other metal foundries use natural gas in the actual furnaces there The stone cement industry Areas that have good amount of clay glass silicone can make cement and The natural gas is actually used to dry the cement which is a wet slurry type when it's processed And of course food processing probably one of the more obvious ones where natural gas is used to fire the massive commercial sized ovens Commercial industries believe it or not you can use natural gas as a source to run very large commercial sized air conditioners So that can be used in space heating and refrigeration Food service industry hotels motels health care office buildings retail services again Mostly this is being used for space heating or to generate hot water Natural gas vehicles have actually been around for a couple of decades There is a push to utilize them more and more they actually using compressed natural gas The most efficient types are dual-fueled so you can use gasoline or natural gas Depending on what's available to you. They are ideal for fleet vehicle usage Public schools will run their buses cities can run their buses companies such as FedEx UPS the US Postal Service can run their vehicles on natural gas any Company that has a fleet of pool cars because they are very very perfect for short-term commuting types of roots and the Part of problems with compressed natural gas vehicles as they exist today is the limited range They cannot go as far as as gasoline fueled vehicles and then of course the refueling stations Most of the types of entities I spoke about have their own refueling stations But there is not the infrastructure across the country yet to support interstate travel with compressed natural gas vehicles I know for instance that it's being studied the use of compressed natural gas in large diesel trucks But again the infrastructure will have to be there. They will have to have refueling stations at moderate intervals for that to become an efficient and practical way to ship goods


Hi, I'm Zane Weisman and I'm a PhD student at Worcester Polytechnic Institute, on land traditionally inhabited by the Knitt Muck people, occupied by European settlers and called Worcester, Massachusetts, since the 17th century. And I'm Tori Thiemann, PhD student at the University of Lübeck in the north of Germany. Today we are presenting our work, Jack Hammer, Efficient Row Hammer on heterogeneous FPGA CPU platforms, which is the result of a collaboration between the two of us, Daniel Moghimi, Evan Custodio, Thomas Eisenbarth, and Burke Sunar. In this presentation, we will explore tightly integrated FPGA and CPU microarchitectures designed for low latency memory sharing in server and cloud environments and demonstrate how these new architectures enable new cache side channel attacks and powerful row hammer attacks. Of course, cloud services have become essential to the way we use computers. What you may not know is that all of these cloud service providers now offer access to field programmable gate arrays or FPGAs to customers who might use them to accelerate tasks like cryptography, rendering, or machine learning. But in the age of spectra and meltdown, we know that hardware security is a major concern when multiple users share the same hardware on the cloud. So what does hardware sharing look like with a modern FPGA CPU system? We studied two similar FPGA platforms, which are both supported by the Intel Acceleration Stack. On one hand, we have the Intel Aria 10 Programmable Acceleration Card, or PAC for short, which you can see on the right. It comes as a PCIe expansion card. On the other hand is the integrated Aria 10 that resides in one package with a Xeon processor. You can see it in the middle. Don't worry if you find this figure complex, we'll explain it in detail later and show it again whenever it may be helpful. For the rest of our talk, there are a couple things to keep in mind. We have to keep in mind the different address spaces we have to deal with. DRAM and caches are addressed using physical addresses, while software processes running on the CPU use virtual addresses. Most of you probably know this. Since the FPGA is considered to be a peripheral, it addresses memory using IO virtual addresses like any IO device does. These IO virtual addresses may be equal to physical addresses if the system does not make use of an IO memory management unit or IO MMU. However, when using an IO MMU, the addresses are truly virtual, or if attached to a virtual machine, equal to the guest operating system's physical addresses. To ease DMA operations on the FPGA, buffers accessible by the FPGA need to be continuous in its address space. Whether or not the IO MMU is enabled, the FPGA driver makes use of huge pages whenever the requested buffer size exceeds 4 kilobytes. The IO MMU will handle address translation regardless of page size. So the second thing to keep in mind is that we can rely on huge page access for all of our experiments. The last thing that needs consideration are the caches and their behavior when the CPU or FPGA reads, writes, or flushes memory. During this talk, we will give insight to the behavior of the caches, which we ask you to keep in mind since we need it to understand why Jack Hammer performs significantly better than Software Row Hammer. So let's come back to the platforms we worked on to give you a first understanding of the Intel Acceleration Stack terminology and technical realization. In the figure, you see again the two FPGA platforms we had access to. On the right, you see the Programmable Acceleration Card, or PAC for short, that contains an Aria 10 GX FPGA and is connected via PCIe to its host CPU. The FPGA itself is split into two regions. The proprietary blue region can be seen as a firmware of the FPGA. It is designed by Intel and provides maintenance functionality, like programming the FPGA or providing sensor data for temperature or supply voltage. In addition, it introduces an abstraction layer called the FPGA interface unit, or FIU, to abstract away the complexity of the available communication buses and in exchange exposes the core cache interface port, or CCIP, to a user's hardware design. The green region, on the other hand, is the partial reconfigurable region, where a user's hardware design is placed. Intel calls a user's hardware design an Acceleration Function Unit, or AFU. On the left, you see the integrated FPGA, which is an Aria 10 GX integrated into a Xeon CPU package. The FPGA is connected via two PCIe ports and one UPI port. UPI is Intel's proprietary UltraPath Interconnect, used to tightly couple CPUs on multi socket systems. Its main purpose is to realize the cross socket coherency protocol to keep all caches in the system in a coherent state. The blue region of the integrated FPGA additionally features a coherent cache and an IOMU, because it could otherwise bypass memory translation by using UPI. As I just mentioned, the integrated FPGA is included in the same package as the CPU. The systems we investigated have several cores with core private L1 and L2 caches, and a shared L3 cache, which is the last level cache or LLC. Memory requests sent off by the FPGA are primarily served by the LLC and are only answered by the system RAM if the request misses the LLC. If the request is sent from the integrated FPGA via UPI, the FPGA cache serves the request if possible, and only on a cache miss forwards it to the CPU's LLC. On the software side, we have the operating system followed by the Open Platform Acceleration Engine, or OPE for short, which includes drivers for the FPGA and exposes an API to the user's software applications. The core cached interface port can be understood as the FPGA side API as it is exposed to the AFU to be used for communication. There are two types of communication available, memory mapped IO, MMIO for short, and direct memory access or DMA for short. The FPGA uses DMA to read from or write to main memory. This way, the FPGA can receive or send bigger chunks of data to or from the CPU. While all MMIO communication runs over PCIe, the FPGA can configure the communication channel to be used for DMA. The addresses provided for DMA operations in general are IO virtual addresses, but not all of our setups make use of the IO MMU, which is why we operate on physical addresses. Back when we wrote the paper, this was also true for the Intel VLab. However, this changed around December 2019. According to the documentation, the CCIP allows an AFU to provide caching hints when sending off DMA requests. For DMA reads, there are two, invalidate and share, which hints the CPU and FPGA caches to cache the requested data accordingly. For write requests, there is a third option called write push invalidate, which hints the CPU to cache the data in the LLC, but invalidates it from any FPGA cache. All caching hints are available for DMA operations sent over UPI, while requests over PCIe only support the invalidate hint. Tori will now take a closer look at the caches and caching hints, but let me say already that we found that the blue regions of all tested platforms including those on the Intel VLab silently drop and therefore ignore certain caching hints. Right, but before I go into detail of our findings concerning cache attacks, let me quickly refresh your knowledge about two important cache attacks, Flush and Reload and Prime and Probe. To run a Flush and Reload attack, the attacker requires access to a Flush instruction and the capability to precisely measure timings. In addition, the attacker needs to share memory with its victim. The attack then works in three phases. First, the attacker flushes the shared memory. By this, the cache line is removed from all caches in the system. In the second step, the attacker waits for the victim to execute and maybe access the shared memory. After the victim executed, the attacker accesses the shared memory and times the access latency. If the access is fast, the victim must have accessed the shared memory, as it is in the cache again. If the access is slow, the data is served from RAM and therefore was not accessed by the victim. In cases where attacker and victim do not share memory or if the attacker has no access to a Flush instruction, Flush and Reload is not an option. Instead, the attacker may launch a Prime and Probe attack if she shares a cache with the victim. For Prime and Probe, the attacker needs to collect an eviction set that contains addresses that, when accessed, completely fill the cache set the attacker wants to monitor. The attack then runs in three phases again. In the first phase, the attacker primes the cache set by accessing all addresses in the eviction set. The second phase again is a waiting phase where the attacker waits for the victim to execute. During execution, the victim might access an address that maps to the cache set monitored by the attacker. In this case, one of the addresses in the attacker's eviction set gets evicted from the cache. In the last phase, the attacker probes the eviction set by accessing all addresses and timing the overall latency. If the probe runs fast, the victim did not access an address that maps to the monitored cache set. If the probe runs slow, the victim must have accessed an address that maps to the same cache set and therefore evicted an address of the eviction set that is now served from slower DRAM. So let's have a look at what an FPGA-based attacker can do. We will first focus on the PCIE scenario where the attacker has DMA access via PCIE. This scenario is applicable to the integrated FPGA and the pack. We assume the victim to be located on the CPU in this case. We started off by measuring access times to see if an attacker can distinguish different locations of a cache line. To do so, we realized the timer on the FPGA by incrementing a register at every clock cycle. This is similar to measuring timings on the CPU using thread counters with the advantage that our timer runs uninterruptible and parallel to all other operations performed on the FPGA. We used the timer to measure access times to addresses we placed in the LRC and main memory. As you can see in the histogram, we have two distinct peaks for the two locations. And even though they are close together, we found that requests served from the LRC are clearly distinguishable from those coming from DRAM because our timer is precise and outliers occur rarely if the LRC serves the request. Let's now focus on FPGA-based attackers that have access to UPI. This scenario is only applicable to the integrated FPGA. In contrast to the previous measurements, we now expect to see three distinct peaks. When using UPI, we can in fact see three distinct peaks. Also, we can see that the FPGA cache has a constant answer time without outliers. This is because the cache is part of the blue region and the preciseness of our timer. The other peaks are really slim as well. This is caused by the high bandwidth UPI and the low system load. Together with the PCIe scenario, this is an important find on the way to running cache attacks against the CPU, since we can do the required measurements for step 3 of flush and reload and prime and probe. However, we still either need a flush instruction or some way of priming the LRC to perform one of the attacks. Even though we can send DMA requests via UPI, we cannot directly send UPI messages since we are bound to the CCIP. Because of this and the fact that the FPGA does not offer a flush instruction, an FPGA attacker cannot run flush-based attacks, but has to rely on eviction-based attack techniques. However, during the previous measurements we found that DMA reads do not alter the location and address is cached at. So we started digging deeper and analyzed the caching hints the CCIP gives us control over. We especially hoped for the right push invalidate flag that is supposed to load data directly into the last level cache. Here you can see a histogram of CPU access times to addresses that were previously written to by the FPGA using direct memory access writes, with the caching hints set to a right line invalidate. This flag is supposed to invalidate the cache line and write it to main memory. To give you a relation, we included the histogram for common memory accesses denoted with MA in black. As you can see, access times to addresses that were written via PCIE are smaller than one would expect when accessing DRAM. And it turns out that these were served by the last level cache instead. This is also true for most accesses to addresses that were previously written via UPI. But some timings are also higher than an access to main memory. These requests come from the FPGAs cache instead of DRAM. So the caching hint does not lead to the expected behavior, but rather behaves like what we would expect to see with the right push invalidate flag. We also tried the other two caching hints that are available for write requests and found a similar behavior. From this experiment we state that caching hints for write requests are not properly implemented at the time of writing. Independent of the provided caching hint, the data is always written to the last level cache. At first sight, this sounds like good news because we were looking for a way to prime the last level cache. However, it turns out that the behavior we see is not caused by the caching hints we add to the DMA requests. Instead, what we see is a CPU feature called DataDirectIO or DDIO for short that allows peripherals to write directly to the last level cache. And since DDIO and its default configuration can only write to 10% of the ways per cache set in the last level cache, this does not allow us to mount a full cache attack against the CPU. However, we can at least provide a proof of concept of the channel we found by constructing a covert channel to send data from the FPGA to the CPU. Our covert channel works like the prime and probe attack, but with the victim willingly sending data. To set this up, we had one software process construct an eviction set for a specific cache set in the last level cache and monitor it like an attacker would in a prime and probe attack. The FPGA on the other side writes to an address that maps to the same cache set whenever it wants to send a 1 and stays quiet whenever it wants to send a 0. This way, the software receives a 1 whenever it sees an increased probe latency and receives a 0 otherwise. To ease the coding, we had the FPGA send with half the speed the software was probing. This results in two probes per bit. Also, the FPGA uses repetition encoding by sending each bit three times to reduce transmission errors. You can see the resulting software measurements in the upper plot. We can see that each peak is followed by a slope because of the second probe and there are always three peaks in the block. On the bottom, you can see the decoded signal. Even this simple covert channel receives a throughput of 94.98 kilobits per second. This could easily be increased by a factor of six if the FPGA doubled its sending speed and omitted the repetition encoding. After we found that DMA reads do not change the location of a cache line, we started exploring row hammer attacks originating from the FPGA. This turned out to be fruitful and ended in the jackhammer attack that Zane will explain to you now. Jackhammer is our implementation of the row hammer exploit that runs on Intel FPGAs and attacks the host system's main memory. To understand how it works and why it's so effective, let's first take a look at how row hammer works in general. Row hammer attacks rely on the attacker having access to memory that's physically located near memory used by the victim. I'll get into how memory is laid out in a minute. The idea behind row hammer is that the attacker accesses one address, then the other, then the first, then the second, and back and forth until a bit in the victim's memory changes value without the attacker ever directly accessing that memory. But when the victim accesses that memory next, she reads the wrong value from memory. So what's going on with the row hammer attack? First, the attacker has to allocate and identify memory located near memory used by the victim. Memory is organized into banks, each of which contains many rows, and all reads and writes at a hardware level target one row at a time. Every physical address is statically mapped to a certain row and bank by XORing certain bits of the physical address dependent on the exact system and memory configuration. The actual corruption in the memory is likely caused by an electromagnetic effect. Each bit of memory in DRAM is stored in a capacitor gated by a transistor. The voltage stored in the capacitor determines whether the bit will be read as a one or a zero. But the transistor allows a little current through the capacitor, even when the memory is not being directly read or written. So it is the duty of the memory controller on the motherboard to refresh every row of the memory no more than 64 milliseconds after the last access or refresh. The prevailing hypothesis for the way that row hammer works is that every nearby row access causes a little bit of extra current through the capacitor, making that 64 millisecond refresh interval no longer sufficient to preserve the values stored in memory. So the simplest and one of the most effective defenses against row hammer attacks is to just decrease that row refresh interval, for example to 32 or 16 milliseconds. This is an option that can be found in the BIOS of most server and many consumer motherboards. A lower row refresh interval means the memory spends more time refreshing rows that aren't being used, so it has a small impact on maximum read and write throughput. But in exchange, it offers substantial protection against row hammer attacks as well as randomly occurring memory faults. Row hammer has been shown to work on lots of DDR3 memory chips and far fewer DDR4 chips. In some cases it can also work on memory with error correcting codes or ECC. For the purposes of this research, we studied DDR3 without ECC because the effects of row hammer on DDR3 are more easily quantifiable, so it's easier to compare across platforms and implementations. We're primarily concerned with row hammer attacks mounted from the FPGAs to the ram of the host system. Our row hammer implementation for RE-10 FPGAs, which we call jack hammer, relies on the CPU for the addresses of the aggressor rows that it will use for the attack. Once the CPU sends a start signal, it runs automatically, repeatedly accessing the specified addresses and, given the right addresses in hardware configuration, causing bit flips in the ram. So how does the performance measure up to a CPU row hammer attack on the same system? The figure on the left shows distributions of hammering rates, that is, the number of memory accesses per second sent by our jack hammer attack running on an RE-10 pack and running on its host CPU, an IV bridge i7. The pack achieves remarkably consistent memory throughput at nearly double the typical rate of the CPU. In the figure on the right, you can see how this translates to the rate of bit flips in the victim row. In many cases, jack hammer is able to flip four times as many bits per second as a CPU row hammer attack on the same system. So what makes jack hammer so much more effective? Well, recall that the row hammer exploit is based on non-linear effects. In every row refresh interval, the attacker is trying to push the bit voltages in the victim memory as far away from the correct value as possible, but at the end of the refresh interval, the row is refreshed and the voltages are reset. So just doubling the rate of memory accesses can make this chance of a successful bit flip during a particular refresh interval substantially higher. But how does the FPGA access the memory so much faster? In short, caching, or more precisely, not caching. When the FPGA reads memory, it does not place a new entry in the CPU's cache. The CPU, of course, caches all of the memory accesses by default. This means that for row hammer to work, the CPU has to flush each address between memory accesses. The FPGA has no such limitation. So let's remove that limitation for the CPU and see what happens. This figure shows memory access rates during a row hammer attack from the RE-10 pack and from the CPU with caching enabled and disabled in the kernel. In the left two columns, you can see that with caching enabled, jack hammer is running about twice as fast as the CPU attack. In the right hand columns, with the memory pages marked as uncacheable, jack hammer runs about 50% faster. But wait, the FPGA doesn't load anything into the cache, so what's saving so much time? While the FPGA can read from the cache, but with the memory set to uncacheable, the CPU's memory subsystem doesn't waste any time checking the cache for a copy of the requested memory and sends the request straight to the main memory. But what we're really interested in here is the rightmost column where you can see that with the cache out of the way and no time wasted flushing memory, the CPU row hammer runs faster than jack hammer could with the cache and almost as fast as jack hammer without the cache. All of those flushes in a regular CPU row hammer attack really add up, but what do these performance metrics really mean for a practical attack? We constructed a fault injection attack against the RSA signature function in the wolf crypt library. The vulnerability was reported and fixed in December of 2019. In this attack, the victim first sets up an RSA key with wolf crypt while the attacker allocates shared memory that the FPGA will use for the attack. The FPGA runs the attack by repeatedly accessing the main memory, flipping one of the bits in an intermediate value used in the RSA signature algorithm. This causes the signature itself to be faulty and also contain part of the RSA private key. The rest of the key can be recovered with either a valid signature computed on the same message with the same private key or with the message itself and the public key. This fault injection against the RSA algorithm has been public knowledge for a couple of decades and is commonly called the bell core attack. We tested this attack with and without the standard defense against row hammer of an increased row refresh rate. In the best case with a standard row refresh interval of 64 milliseconds, jackhammer caused a fault an average of 25% faster than a CPU row hammer attack. But with the refresh rate doubled, jackhammer was 185% faster. We took a couple of shortcuts in our setup of this attack, neither of which affect these performance measurements. The first is that we manually located memory to be used by the attacker and victim. In a realistic scenario, an attacker would use a technique known as page spraying, allocating and deallocating memory pages until the right setup is reached. Page spraying can also be assisted by using cache attacks to monitor the memory usage of the victim program. The other simplification we make is that we directly flush the memory used by the victim program. Realistically, an attacker would use an eviction set to force the memory out of the cache and cause the victim to read from memory, where the row hammer attack has caused a fault. In conclusion, we identified and verified timing leakages on the area 10 platform. We analyzed the caching hints that are available and constructed a covert channel from the FPGA to the CPU that reaches 94.98 kilobits per second. We also showed that FPGAs can be used to accelerate row hammer performance by 25% and used this to demonstrate a fault injection attack against the RSA implementation of Wolf SSL, which resulted in the CVE you can see on the screen. Thanks for your attention. Feel free to read our paper for more details and if you have any questions, come and ask them during our Q&A session at Chess 2020 or send us an email.


We continue our journey through the month of Ramadan. We pray to Allah subhanahu wa ta'ala to continue to bless us. While there's other things I want to share, since we are still at the beginning of Ramadan, there's this very lengthy hadith narrated by Salman Al Farsi, from the Prophet ﷺ and I want to share some portions of that. It's a very lengthy hadith. While some have mentioned that it is a weak or a weak hadith in reality, we are reminded that in terms of merits, fadail, it is okay to accept the weak hadith as well. There's Salman Al Farsi, who says that when it was the final night of Shaaban, the Prophet ﷺ gave a sermon and in the sermon he said and then he continues and I'm going to share about three to four things from that sermon. The Prophet ﷺ said, O people, the month of Ramadan has come with its mercies, blessings and forgiveness. Allah has decreed this month to be the best of all months. Its days are the best amongst the days, its nights are the best amongst the nights and the hours are best amongst the hours. This is a month in which you have been invited by Allah to fast and pray. Allah has honored you in it. In every breath you take, there is a reward. And why? Because we're in a state of ibadah and worship.  Therefore invoke your Lord in earnestness with hearts free from sin and evil. And isn't this what we do? As the month of Ramadan begins, even those amongst the ummah who may be doing certain things wrong, stop. That's a sign of their love for Allah, their love for the deen. That's their taqwa. And the Prophet ﷺ continues and says, And pray that Allah may help you keep fast and recite the Holy Qur'an. Indeed, miserable is the one who is deprived of Allah's forgiveness in this month. Reminds us of the other hadith of the Prophet ﷺ where he was climbing the pulpit. And Jibrail came ﷺ to him and the Prophet ﷺ was made to say, Ameen to a du'a that Jibrail made against those individuals who he said that find the month of Ramadan and they have not been forgiven. So forgiveness is a big thing during this month. Now I'm going to skip a few portions and he continues.  Make it free by invoking Allah for forgiveness. Your back may break from the heavy loads of your sins. So prostrate yourself before Allah for long intervals and make this load lighter. So even when we pray the Fardh prayer, Fajr, Dhuhar, Asr, Maghrib, Aisha, make the Sajdah a little longer. Right. Be in there. Make, instead of saying that this be three times, maybe say it five times. I'm not asking you to do seven or nine. Just do it three times, but do it with love. Do it with compassion. Do it nice and slow. Lighten the load and the Prophet ﷺ says, Understand fully that Allah has promised in his honor and majesty that people who perform Salat in Sajdah will be guarded from the hellfire on the day of judgment. May Allah protect us all. And then there's a lot he continues. And then towards the end he says, Whoever offers recommended prayers during this month, you know, Before Fajr, there's two Sunnah. Before Dhuhar, there's four Sunnah. After Dhuhar, there's two Sunnah. There's a four Sunnah according to some hadith before Asr as well. Two Sunnah after Maghrib. Right. Two Sunnah after Aisha. In fact, those twelve rak'as. Two before Fajr. Four before Dhuhar. Two after Dhuhar. Two after Maghrib. And two after Aisha. That's twelve. The Nabi ﷺ says whoever prays twelve rak'as in a day, Allah will build for them a house in paradise. Right. Not like one house every day. And those are all, in a sense, not obligatory prayers. Voluntary prayers. Of course, a higher degree of it being voluntary. They're referred to as a Sunnah Muakkadah. But the Nabi ﷺ says whoever offers the recommended prayers during this month, Allah will save him from hell. And whoever offers, and according to one narration, will get the reward of an obligatory prayer. And then he continues and says whoever observes his obligations during this month. In other words, fulfills the obligatory prayers. Their reward will be seventy times their reward during other months. Right. So for Fajr, time seventy. Dhuhar, time seventy. Asr, time seventy. Maghrib, time seventy. Aisha, time seventy. And then if you do it in congregation, congregational reward is already times twenty-seven to begin with. So do the math. Twenty-seven times seventy. Right. Our reward is massive with Allah ﷻ. And then he continues and says whoever repeatedly invokes Allah's blessings on me. Salawat. Salawat and Nabi ﷺ. Allah will keep his scale of good deeds heavy while the scales of others will be tending to lightness. Right. Whoever recites during this month a single verse of the Quran will get the reward of reciting the Quran in other months. Right. The whole Quran in other months. So increase in our tilawah to Allah ﷻ as well. We pray to Allah ﷻ for goodness and blessings and reward and acceptance. In shā'a Llāh. Peace be upon you.


I said stop. Oh Sorry, I didn't see you were here What time is it?  I forgot to create a video, but since we're at it. Let me show you how I do my overhead shots Hey, what's up guys and welcome back to my channel So the previous sequence you just saw of me waking up the whole morning routine These were all examples of top-down shots a lot of tech youtubers use these types of down-facing shots to get the different Unique angles of products. They are reviewing. It just looks really awesome And is a great technique to incorporate to your videos So let's get started. The first setup would be using a tripod. This is definitely not the best Solution, but I think most of you guys that are watching this video have at least a tripod at home There are certain limits to it depending on the tripod you have and how you want your shot to be I find it difficult because I more likely get the legs of the tripod in the shot And I also don't have a large area to film giving me limited space a better option would be using a Background stand with a multiple clamp. I use the Coleman flex, which has a one-quarter threat mount to mount my camera It's extremely robust and tightens up very well so that the camera stays safe The great thing about this setup is that you don't really need to add any counterweights Since both stands keep the camera stable the downside to it is that the setup takes longer and uses a lot of space This is more of a permanent setup So if you're doing a bunch of tabletop videos, then this might be the right solution for you Another way to set up an overhead shot is simply using a C-stand. Since it's made up of pure metal It's pretty heavy and you don't really need to put any extra weight when mounting a mirrorless camera At least with my Sony a7 III. It's adjustable making it really easy to move the camera in all directions So if you have some extra money, definitely spend it on a C-stand. If it's too heavy You might want to use sandbags to support the stand leveling out the weight so that nothing falls and breaks the camera as a Bonus tip with a really heavy and expensive Camera that is difficult to mount a great hack is to use a mirror hanging above the Countertop just tilt up the camera and zoom in on the mirror and there you have it already a nice Overhead shot the image and letters will be reversed, but you can easily fix that in post This is a safe and inexpensive method Let's now take a look on how to make your shot look nice I use a wide-angle lens like the Sony 16 to 35 because it allows me to capture a wider Area giving me more space in my shots A great thing about using a zoom lens is that I can always adjust the framing by changing the focal length For the focus mode I leave it at autofocus the autofocus on the a7 III does a really great job For overhead shots, I always shoot in 4k. This allows me to crop in and post This can help if I want to adjust the framing to get different shots or to correct the horizon if that wasn't done Well now in order to check your shot You can use the flip-out screen if your camera doesn't support it The best way is to simply use a monitor if you have the Sony a7 III you can wirelessly connect it to your smartphone Using an app if not use a monitor that connects by using an HDMI cable with a clamp You can mount the monitor on to the stand this way you can constantly monitor What's in your frame a great tip is to mark out the frame lines on the surface using tape or drawing it out with a pencil This way you have an idea of where the frame is when you're showing off the product for my single light source I will be using the aperture 120d with the light dome 2 if you don't have a softbox You can also use natural light. I find this the best light source But it can be difficult controlling it because if you have direct sunlight the shadows might be too harsh giving you a contrasty look another option would be mounting a small light like the aperture MC on to the stand Using a clamp the key when using light is to keep it soft by using a diffuser and keeping it close to the subject That is why I prefer using a softbox. It just gives me more control and Offers a very soft light set it up high so that it points down to around a 45 degree angle You want to make sure that it's evenly lit creating a sort of soft spotlight for the backdrop You want to choose a surface that doesn't reflect you want to choose something that fits the product neutral surfaces like concrete floor Wood color backdrops also wrapping paper another thing another thing another thing to consider is adding Decorations like plants or other things that make the shot look more interesting. So that was it guys So these were a few ways on how to set up an overhead rig for your videos If you did, please leave a comment and let me know in the comment section below. What kind of set up you use Don't forget to subscribe to my channel. We are soon reaching 1,000 subscribers I can't wait follow me on Instagram at Ben at grazer and as always see you in the next video


Hi it's Vicky here and welcome back, today I'm going to share 3 cards, all of them have really interesting designs with a fun element for the recipe, so for the first card I create a lovely dimensional scene with the flaps, on the second one you get the gear that actually moves on the swing, and the last one is absolutely adorable, it's a window gatefold card that features the shape of the bunny on both flaps. So for the first card I have a white cardstock that's 4.25x5.5, that's the standard card size, and I also cut out of green cardstock 2 slopes just by using a couple of dies that I had, these have a lovely stitching, so they create a great detail. Now both those green cardstock are a little bit wider than what I need, so I'm going to make sure that I cut them out, and instead of cutting the width to be 4.25 which is the standard size, I need to have a quarter of an inch extra so that I can wrap it around my card, so that's actually 4.5x5, and here is how my card is going to go together once I glue everything, and you will be able to open up those front green flaps. Since I'm going for a little scene I'm going to create the sky here, and this is the main backing of my card, so for that I'm using a stencil that creates this lovely detail, and with my brush I'm adding a little bit of ink, I really want this to be quite subtle that's why I don't load my brush with too much ink, and that's why I prefer to use a brush instead of that blending tool that adds too much ink on your paper. Now with all the lights that I have on my crafting area you can't really tell, but you will see that it's quite visible at the end photos. I used a piece of green cardstock to stick it down at the bottom of my panel to complete my scene so I have the sky and the green grass now, and I'm going to go ahead and do some stamping. All my images for this card come from a new stamp set which is called Easter Bunny's, this is one of the designs by Stacy Yakula for my favorite things, it's one of my favorite designers and I absolutely love all her stamps. If I'm not mistaken they release one stamp set from her every month and I absolutely recommend her designs, check them out you will absolutely love them. So now I'm going to use my alcohol markers to color everything, my two bunnies, the eggs and the butterflies and then I'm going to use the matching dice to cut out everything. Now I added some double-sided tape at the back of those flaps and I'm going to put my card together. This is a card where the inside is exposed, the flaps are part of the design and they actually create my heels and on the inside of those flaps you can write your message.  I don't mind at all so I'm just going to leave it as it is. However, the back of those colored images bothers me since the ink bleeded through I used the Nina Solar White cardstock which is the 80 pounds so I'm going to cut out two more images of those bunnies and I'm going to stick them at the back, this way I have a nice and clean backing. Before sticking them down I'm using Nouveau Del Luxe, this is liquid glue which allows me to slide them until I have the perfect fitting. Now I can stick all those cutouts on top of my card and I'm using foam squares to secure them down making sure that the foam squares do not show as I open the flaps. I'm also going to stick my butterflies on the sky as well as the stack of eggs on the inside of the card. Now I do have a couple of butterflies here but you will see at the finished photo I added a third one. Now for the sentiment I went with Happy Easter which is one of the sentiments included in the same stamp set as the bunnies which I have just stamped on white cardstock, cut it out with a die that has a fish tail on one end and just stack it down. And finally I used my cropped dial to round the top edges since this is the front and the inside of my card. It's a really adorable card, perfect for wishing Happy Easter and here are some close-up photos. Now let's move on to the second card, this is going to be really fun. The stamp set that I'm using here is called Start Each Day with a Wii.  This is a new stamp set by my favorite things and it comes with three sentiments as well which I'm going to use one of them on my card today. So here is my girl all colored and ready to go. Now I'm going to use a die set by my favorite things which has just been released. It gives you all the parts that you need to create an interactive swing. Now I will be using this large one and I'm also going to use this. This can work as a tree or it can work as a cloud. So it makes designing cards really versatile and also it gives you in the set a swing. So you can add on your swing anything you like. I'm going to use double-sided tape on this big cutout piece here and then I'm going to stick on top the girl but there are many different ways on how you can put your swings together and make sure to visit the YouTube channel of my favorite things. You will find there a video by Stefanie where she creates three cards using this die set in different ways. Now I have this ring at the top and I'm going to use a foam circle that I have here. I'm going to place it inside the circle and this has adhesive at the bottom and at the top and on top I'm going to stick a little paper circle that I have cut out. So here you can see how easy it is for the little girl to swing and now of course I have to cover up that mechanism somehow and that's where that trick comes in. So I have used foam tape all around making sure that I don't block the bottom as I want my girl to swing easily.  I also added a sentiment from the same stamp set as the little girl and you can of course take your card a step further if you stick down little flowers or even clouds to your sky or birds and butterflies flying around. There are so many ways to dress up this design even more. For the last design for today I'm going for a window gatefold card so I have two standard cards here. These are both four and a quarter by five and a half and I have folded the front flap on both of them in half and then I can place one inside the other. I do have another video with gatefold cards which I am going to link for you at the end of this video if you want to take a look. I have double sided tape at the back of one of the cards and I'm going to slide one on top of the other, stick them together and just make sure that everything is nicely aligned. So my card press is now ready. All I'm going to do is to cut out a window, I am going to use this die, this comes from a new die set by my favorite things from the latest release, it's called the cotton tail cutie, it's absolutely adorable and I love the fact that it is symmetrical and that's why this is going to work for this card. So I secured that on the front flap and I'm going to run it through my pick shoot making sure that I keep the flap folded. And since I'm trying to cut out two layers of cardstock I'm going to run it a couple of times through my pick shot making sure that this is going to cut out all the way through. Now I'm going to fold my card again and without moving the die at all I'm going to secure it on the other flap. Then I will remove the purple tape from the first card that I did and now I'm going to run the other side by doing so I know that the die hasn't moved at all I'm going to end up with a nice continuous design where everything is perfectly aligned. Again I'm going to run it a couple of times through my pick shot making sure that the die is going to cut out through the two layers of cardstock. And here is my card base ready to go, you have a window at the center but when you open up the flaps you do get those bunnies on each side, absolutely adorable. Now for the inside I'm going to create the bunny and that's just paper piecing I'm going to cut out all the pieces from white cardstock and then I'm going to cut out a few more from the pink cardstock that I have for my card base and now it's just a matter of putting everything together with glue.  And if you have any other dies that cut out animals that have symmetrical faces you can create this design. I know that my favorite things has more animals like this one and if you have any of the picture book by Simon S. Stump dies they work great for this design as well. So I'm putting all those little pieces together for sticking down everything I'm using my Nouveau Deluxe, this is my go-to liquid glue, I absolutely love it just because it never clogs on me.  Mine is holding a little banner that says Happy Birthday. The sentiment comes from the stamp set which is called Birdie Brown Greetings Galore. It's packed with greetings for every occasion and my super adorable card is ready. I'm going to keep everything closed with a ribbon and of course you can create a little band to keep your card closed either with cardstock or with vellum. This design is really easy to make and recreate but it creates a really wow factor for the recipient especially since you end up having bunny windows on both flaps. So these were the cards for today, I hope you had fun and you got inspired. As always you will find a full list of all the supplies that I used down below in the description area as well as on my blog. Don't forget to like the video and share it with your friends if you had fun watching and thank you all so much for spending some time with me today.


What's up guys, Mike Dakota here. Today we are going to go over the sliding window algorithm and we're going to see how we could apply the sliding window algorithm into many different types of problems. So then if you could see this similar problem of the sliding window, you could apply this algorithm to those problems. This video is not going to go over each individual problem in depth. We're just going to explain the sliding window algorithm in each of these situations and how you could apply them to each of these problems. So what is the sliding window algorithm? The sliding window algorithm is used to find problems involving contiguous sub arrays or sub lists. Okay, so as you can see in this picture right now, we have a sliding window. What does this mean? It means that we have basically this window that we're going to add values into it or we could remove values after it. Okay, so we have 11512, right? If I move this window forward, this window now shifts to the right and we have 15126. So essentially it was what we're doing. What we did here is that we removed the one and we added a six into this window. So this is what a sliding window is doing. We're taking, we have a window here and we're just moving this window either forward or backward down our array. So what is the sliding window? When do we use a sliding? Many problems to deal with sliding window is that we need to calculate something or find something out of contiguous sub arrays of a given size. So what do we mean by contiguous sub array?  So in this big array of 1326-14182, a sub array would just be picking any elements. So if I pick like a four, and then I pick two, right? And I put that in a new array, four, two, that would be a sub array, a new array that is part of the small array part of the bigger array of 1326-14182. But what they want is contiguous sub arrays. So what does contiguous sub array means? It means I can only take one after the other. Okay, so that means that negative 1418, this sub array, negative 1418 is contiguous. Okay, that means I can only pick elements one after the other. I cannot just take negative 1418 and then pick a one here also from and merge them together as a new array of one negative 1418. Okay, that's not allowed. Okay, we cannot do that. We can't just pick elements randomly and have some space between they have to be one after the other. So that's what negative 1418 is a contiguous sub array. Okay, so now in this problem, given an array, we need to find the average of all contiguous sub arrays of size K. So what does that mean? So let's say K is equal to five. What essentially what we need is we're trying to find the average of all contiguous sub arrays of size five. So what does that mean? That means that we're just going to go through all the elements in this array. And we're going to go to each contiguous sub array of length five. So if I start from one, and because they have to be one after the other, because they're contiguous, I have to just count five elements including one. So here I have one, and then I have to count five elements. So I have one, two, three, four, five. So I'm going to add that negative one. So this would be a contiguous sub array, right? One, three, two, six, negative one. And this is a contiguous sub array of length five. So because they want the average of all contiguous sub arrays of length five, what we're going to do is we're going to add them up. Okay, we're going to add up, we're going to sum up all these elements of one plus three plus two plus six plus negative one. And we're going to divide by five, because that's the average, right, the length is equal to five. And the average is you is the sum of all the elements and divided by the length of it. Right. So then in this case, we have the first contiguous sub array of the average is going to be one plus three plus two plus six, plus negative one divided by five, we're going to get 2.2. Okay. So that's the first contiguous sub array. Now we want to go through there all of them, right? So now we have to go to the second one. So what's the second one more? Well, starting from the second element, we're going to count a length five. So starting the second element right here, we're going to count five elements of it. So one, two, three, four, five. So this would be the second contiguous element of length five, right? Three, two, six, negative one, four. Right. This would be the second contiguous sub array of length five. So then what do we do now? We're going to sum them up and divided by five. So what they do here is that they do three plus two plus six plus negative one plus four divided by five, they get 2.8. Okay. So that's the next element, right? And then now we're going to go through the next contiguous sub array. So here, this would be the next contiguous sub array, the third element starting from the third element, and then length five. So third element is two, and then we're going to count five elements of it. So we're going to do two, six, negative one, four, one, right? These are five elements starting from two. And what we're going to do is we're going to add them up. Okay, so we're going to add them up. So we're going to two plus six plus negative one plus four plus one. And I think that's, that's 2.4. Okay.  Yeah, what it is, what is okay. And then after that, we got to add up the last one, negative one, four, one, two, sum them up divided by five. And that's our last value of 2.8. Okay. So that's how you would calculate the sums individually. And just starting from each of the indexes, and then go looping through, and then we're going to go through every single five elements, starting from each of the indexes, and then adding them up and dividing by five. Okay. So what would the algorithm look like? Well, what it's doing is it's going to go through the number of sub arrays inside the, the array, and then they're going to go through every length of five, right? So the, so their first loop is going to start from zero, it's going to go through n minus k, right, that's going to be the last ending, the last spot that they're going to end at. And their second loop is just going to sum up each of the individual sub arrays. So that's going to start J is going to equal to I, which is like where they started from the beginning, and they're just going to loop up to I plus K, which that means is that they're going to loop through every five elements, okay, they're going to loop through every five elements and just continue going so on and so forth. So the sum is going to start from zero, and it's going to go from R of J, and it's going to just keep adding up for every single five elements, and then they're going to calculate the average and divide by K. And they just store that into like the next index in their resulting array, and they return it. So this is just going to go through every single length of five of a sub array of five, and then just sum up, sum them up, get the average, and then put that into a new array. And this is just takes all time complex to n times k, because there's two loops, and then the size of it would be k, right? So there's k, there's k size and you got to multiply by n, which is n times k. So what's the problem with this solution? Well, the problem is that we're recalculating overlapping parts. So in the first sub array, we have one, three, two, six, negative one, right? And we sum them up. Well, our second sub array, three, two, six, negative one, four, is recalculating the sum of three, two, six, negative one, right? They're overlapping parts that are actually overlapping that we're recalculating, which is not actually what we want to do. So the most efficient way to solve this problem is actually just to have a window of five elements, and then just move, reuse the sum from the previous sub array. So we're going to subtract one element out of the window. And then we're going to add a new element from the right side into our window. So it saves us from having to recompute this previous sum over and over again. So the time complexity gets reduced to o of n. So in this, in this sub array, we can take a sub array, we have one, three, two, six, negative one, we're going to remove, subtract this one from the beginning of our sub of our sliding window, and we're going to add four next element of four into our sliding window. So then we're going to still have five elements here. And we already have the previous sum that we've calculated. So we don't have to recompute that over and over again. So how do you code this problem? Very easy. Okay, all these solutions are in Java, but you could do the exact same thing in JavaScript in C++ and C in Python. The same concept applies to all these languages. Okay. So how do you code this? We're going to have the ending of our window, we're going to loop from zero to the length of the array. Okay. And what we're going to do is we're going to have a variable called window sum, it's going to add up all of the out of the current elements, all right, of our window end. Okay, so we're just going to sum up the values in in window sum. Okay. Now, if we reach size K, okay, so if this if statement is just checking if we if window plus one is greater than equal to K, right, or a window end is greater than equal to K minus one, this is just checking if we've reached K values already. Okay. So if we've reached the size of K values, what we're going to do is we're going to calculate the average. So we're going to store the result of our array, this result is an array, right, we're going to store the results of a window start, which is just going to be another variable equal to the average, okay, the average is going to be a window sum, which is our current sum divided by K. Then what we're going to do is we're going to move the window down. And to do that, we're going to subtract the current, the first element out of the R window start, okay, so it's going to be going to remove whatever element it was at the index of window start, right? So we're going to remove the element of whatever was at the window start out of our sum. So we're going to subtract it out of our window sum. Then what we're going to do is we're going to shift the index of window sum, window start down, down by one. So it's going to essentially slide the window down ahead. So if what it's doing is it's removing the first element, and they're going to move the next index downwards, then we're going to go to the next elements, and then it's going to continue on so on and so forth, as the window start, as window sum goes to window end, and we reach the end of our array. So that what's that doing is that's going to maintain the window loop through, maintain the window of five elements, remove the first element, add the next element, move the first the next element, have the next element, so on and so forth, maintaining five elements in our current sum. And every time we have five elements, we're going to calculate the average, and then we put in our array of result, and then we return it. Okay, so that's what this whole algorithm is doing. All right, let's go over another problem. Maximum sum sub array of size k. So given an array of positive integers, and a number k, find the maximum sum of any contiguous sub array of size k. So what is this, it's basically the exact same problem. But instead of finding average, we're going to try to find the maximum sum. So let's just actually look at the code right now. If you look at the code, it's literally very, very similar, exactly the same thing. Or instead of having an average or a current sum, we have max sum, we have window sum, we still have the same window sum, right, we we have still have the same window sum, we have the window end, starting from zero, going up to the length of r dot length, we still have window start, equal to zero. And then we're still summing up window sum at each of the current elements currently. And we still have this if statement, if we reach a length size of k, right, if the window end is greater than equal to k minus one, this is just pre checking if we reached the size of k array. Now the only difference is that we have is that now, instead of taking the average, we're going to get the max, right, so we're going to get max. And we're just going to have the max of the, we're going to just try to get the max sum. So to do that, we call max function and pass in our max sum, and the current window sum that we're passing in, going through and summing. Now here, we're still going to remove the first element from window sum, as we go down our array, and we're going to still increase the window start, which is the index of window start of whatever windows are starting to the next element, and then we maintain five elements going downward. But this time we're trying to find the maximum sum. Okay, and then we return maximum. So this is pretty much the exact same very similar code. Only difference is that this time they're asking is maximum sum of any contiguous sub array size k. So instead of maximum sum, instead of average, they're asking maximum sum, okay, of contiguous sub array. Okay, so once you see this, you should realize this is not that very difficult. Alright, so next let's go over the next type of problem. This time, smallest sub array with a given sum. So given an array of positive numbers in a positive number s, this time, find the length of the smallest contiguous sub array whose sum is greater than or equal to s. So this is very, very pretty much very similar to the previous problem, except instead of having a fixed window length of k, this time we're given the sum s and we need to find the smallest length. We need to find the smallest length of the smallest contiguous sub array, the length of the smallest contiguous sub array, whose sum is just greater than or equal to s. Okay, so let's just go directly to the solution now, because it's really not that hard. So since we don't have a window anymore, like we don't have like a fixed length, we're just going to loop from zero. We're just going to assume we're going to loop from zero to the end of the array, right, and that's going to be our like a window size. Okay, so this is just going to be like, like the size of our window, right? Our window is going to shrink or increase or shrink. Okay, what we're going to do is we're just going to sum up the elements in this current window size. So our current window size is going to be zero, and then it's going to go to the length of the array, right? Now, what we're going to do is while this sum, this window sum is greater than or equal to s, right? So this is very similar to the whole sliding window algorithm. But this time, while the window sum is greater than or equal to s, so this is like the s is like the sum that they give us now. So this time s, they give us the sum, but we need to find the smallest length, right? So while this window sum is greater than or equal to the s, what we're going to do is we're going to calculate the minimum length. And to do that, we have this variable called min length. And we set this equal to some like infinite large value, right? And we're going to calculate the length of it, the length of our window by taking the window length, window end, which is another variable, right? Window end minus window start, which is going to be zero in the beginning, right? I think window end is, did they define it here? I think they defined it, defined it somewhere here. I think they, I don't know. But yeah, so take window end minus window start and then add one so that basically counts for, wait, I think, I think this should have been window size. They didn't define a window end. So this is like, this is a problem. This is like a typo. So I think this should be window size. But essentially is that what they're doing is that they're going to have a fixed starting from zero and go to the length n, and they're going to sum up continuous sum up of the current values in the array. And then while this sum is greater than equal to s, they're just going to calculate the length by taking the window of the window end minus the start and the plus one, which is going to give us the length of each of the array. And then what they're going to set that equal to the smallest min length, equal to our variable of min length, to calculate it, use a min function, and set that set set this length is going to the minimum value of this giant length is going to equal with the minimum current min length, get the smallest value between both these two values, calculate it put in min length. And then we're going to reduce our window size. So what we're going to do is we're going to subtract the windows window start, which is going to be the starting value of our starting index, we're going to move it up by one. And then we're going to yeah, we're going to remove that from our window, the first element we move that from our window, and then we're going to move increase our window start plus plus. So instead of having a fixed length, this time, we are just looping through zero to total length, and then summing them up. And then while it's greater than equal to s, we're just going to subtract it, right, subtract the star window start, like a subtract our window length, over and over again, and move the window downwards. Okay, so that's what this is doing. In the end, if we min length is equal to still equal to infinity, then it's zero. Otherwise, it's we're just going to return min length. So yeah, that's essentially how you do this problem of smallest sub array with a given sum. Instead of having a fixed length of k, we're trying to find the smallest k smallest length, let's go over the next problem. Given a string find the length of the longest substring in it with no more than k distinct characters. So this is very, very, very similar. Okay, so when they mean that no more than k distinct characters, they mean that we don't want more than k distinct characters, we want the length of the longest substring in it with no more than k distinct characters. So how do you do this problem? Let's just go to the solution right now. We're going to our window now is going to be a hash map storing the frequency of each character. Okay, so that's what they have here. And then what they're going to do is that once we we're going to keep storing the frequency each character, and we're going to have a, a index of the start window start and the index of the window end. And what we're doing is that we're going to keep adding more values into our hash map, right? And what we're doing is that if we reach k, so they don't want they want they don't want more than k distinct characters, right? So if our size of our map is greater than k, we're going to move the window to the to the right. Okay, and we're going to decrease the frequency of the leftmost character. So that's what they do here. So they get the leftmost character here. And then they're going to decrease the frequency of it. So that's what this put thing is doing is decreasing the frequency of the leftmost character. And then if if it is equal to zero, right, so if the frequency reached like zero or negative or whatever it is, they were just completely remove it out of out of the out of the map, because like, what's the point of it, right? And then they're going to increase window start, which is they're just going to move the window downwards, right? So instead of having like our window being an array, our window is now a hash map. And we're just moving the window downwards for the number of frequencies so that make sure that our size is not number distinct characters is not not greater than k, right? It has to be no more than k distinct characters. So that's what they do here. So that's what this sliding window is doing down here. And then they're just going to get the maximum length, getting max length minus window start plus one, which is going to get the length of the window. And then they store that in a variable called max length, and they just return it. So yeah, that's this part here. So yeah, what they're doing is very, very similar. Put a store in a hash map, add one to the right every single time. Once we reach k distinct characters, move the window from the start, remove the first element of the characters in the first window on the left side of the window. If it reaches zero, we remove it from our map window. And then we're just going to move the window start down by one. And then we're going to calculate the length of our window and the star window start and window end. Okay. So yeah, that's the gist of this problem. And let's go to the next. Okay, next problem 1.4 fruits into a basket, given an array of characters where each character represents a fruit tree, you're given two baskets. And your goal is to put the maximum number of fruits in each basket. The restriction is that each basket can only have one type of fruit. You can start with any tree. But once you have started, you can't skip a tree. You will pick one fruit from each tree until you cannot pick it. And you will stop when you have picked from a third fruit type, write a function that returns the maximum number of fruits in both of the baskets. Okay, let's just go directly to the solution. It's very, very similar, except essentially is that we need to find length of the long sub array with no more than two distinct characters, which is the fruit types. So it's very similar to the last problem. Have a hash map storing the frequency of each character, loop through from our starting window to the end, increase the frequency of it, while the free the number of distinct characters is greater than two, going to decrease the frequency of the starting value of our window, if it equals zero, remove it from our window, then we're going to increase the window start, which is the starting index plus one. Then in the end, we get our, we calculate our length of our maximum fruits by taking window and minus window start plus one, so that calculates the length, and then we return it. So it's very similar to the previous question. Okay, so next problem given a string find the length of the longest substring that has no repeating characters. Okay, it's very similar. We're going to have a hash map that stores the each character, and then this time it's going to store the index of each of the last character, okay, of the last character that we go through. So we're going to maintain our window going from zero to the end of our string, and we're going to get the last character at the current window. And what we're going to do is that if we already contained this right most character, right, if we already can process the string, have a repeating character, what we're going to do is we're going to move the starting window down by one, right, move it down. And then essentially is that whenever we get a repeating character, we will slide our window to ensure that we have distinct characters in the sliding window. Okay, so we're going to, yeah, we're going to get the maximum start window start and then the right most character plus one, where we'll start down. And then we're going to put the right most character, right character, our window and put that that frequency there, like not frequency that that index there.  And then we return it. So yeah, it's very similar. But this time, the hash map, our window stores the last index of each character. And if we get a repeating character, so if it contains this character, we shrink our window to make sure that we all have distinct characters. Alright guys, this is the next problem of sliding window, the longest subarray with same characters after replacement. So you're given a string s in integer k, you can choose any character of the string and change it to any other uppercase English character. So basically, we have a string and we want to change this character. We could change this character to an uppercase at most k times. And after this, we need to return the length of the longest substring containing the same letter you get after performing the above operations. So if we just go into the solution here, it's pretty much the exact same thing. So instead, we're going to have a frequency array, and this is going to be our window per se. And then we're going to have the frequency care letter, we have the left index representing the left side of our window. And then we have max the max length, okay, max length of the letters to replace. So what it's doing here is it's going to go from the right window to the end, sorry, from zero to the length of the string, we're going to mean to increase the frequency of each character at each certain number, right, each character. So character A would have a frequency, we're going to plus one character B would have another frequency plus two. And then what we're going to do is we're going to get the most frequent character, maintain this as a variable, and using the frequency array, maintain most frequent character. And what we're going to do is we're going to take the window that we're having so right minus left plus one. So this is like the length of the window. And then we're going to subtract by the most frequent character to get the number of letters to change. So because we're changing a certain number of letters, right, to become uppercase, right, at most k times, we need to get the amount of times that we're changing it. Right. So we're taking the length of the string that we're going through, like the length of our window subtracting by the most frequent character, the frequency of the most frequent character, right, and that's going to give us the letters that we're changing. And if it's greater than k, then that means that we have to move our window up. So what we're doing is we're going to decrease the frequency of the starting left side of the starting window, and increase it, go to the right side, right, the left one is going to go to the right, and then we're going to get the max of our window again. And then after that, we just return max. So this problem is very similar to the previous problem. Next problem is very similar, 1.7, which is the longest subarray with ones after replacement. This time we're given an array of ones and zeros and a number k. And we need to return the maximum number of consecutive ones that we could flip at most k times to get zeros. Okay. So if we look at the solutions very similar, this time we're going to have same variable max, zero count, which is going to represent like a counter for the current window. Then we're going to have our left pointer, which is like the left, the left side, i is going to represent the left boundaries of our window. And j is going to represent the right boundary of our window. So we're moving j from zero and going to the length of n. So if the number is zero, because in this problem, we're given ones and zeros and we want to flip them to most k zeros, right? So if it's equal to zero, we're going to increase the count of zero. And then while the count is greater than k, what we're going to do is we're going to move the left window to the right. So here we're decreasing the count of the zero count on the left side, and then we're going to increase the left pointer of our window to the right, right? We're going to increase the left pointer to the right. And then once this is done, we are going to get the maximum length of our window. And that's, and then we're going to return that. So it's very, very similar to the previous problem. Only difference is that instead of zeros, it's like, we're trying to flip zeros and ones instead of like strings. But yeah, that's very, very similar. Next problem we're going to go over is given two strings s one and s two return true if s two contains a permutation of s one. So in this case, we have a b. And here we have e i b e i d b a o o o. So since s two contains a permutation of a b, such as b a, that's going to be the output. It's going to return true. Yeah, whereas here, a b, there's no b a value here, there's a space, there's an o in between. So this returns false. Okay, so that's like the inputs. So in this problem, the easiest way is to create a frequency array for both of them, add them up. And then if one of the both of the arrays are have the same number of frequencies currently, while you're looping through them return true. Otherwise, we're going to decrease the frequency, increase the frequency of the rightmost, and then decrease the value of the current character, to the rightmost also. So we're basically just decreasing increasing and decreasing it while we're looping through the difference of the two lengths of the two strings. Okay. So yeah, now this is pretty difficult. This can actually get further optimized because instead of updating it, we could actually keep a counter. So here we're going to have the same sliding window now. So to do so, we're going to maintain a counter variable which stores the number of characters, which have the same frequency of s one and s two. And as we slide the window down, we deduct the last element and added a new element to a new frequency of characters, increasing it by one. Otherwise, you keep the count intact. Okay. If it was earlier added, it now leads to a frequency mismatch. So we need to decrement the count variable. So we have to shift. So after shifting the window, if the county equals to 26, that means all of them match. So in this case, we have the same frequency array for s one string and s two, we're going to keep counter that this time we're going to have a count variable. Then we're going to loop through. Yeah, we're going to loop through a counter counting how many characters are the same in both of the frequency arrays from the first one and the second frequency, and we increase it. Now this is where we have our sliding window. So here, what we're doing is we're going to start from zero and we're going to go through s two dot length minus s one. And then we Yeah, so here, this is our rightmost window, R. And this is just like a frequency of it. And this is the leftmost. And this is like the character number of the frequency. No, not frequency. My bad. It wasn't frequency. This is like the right index. And then it's like the left index. Okay. What we're doing is that if the count is equal to 26, that means that we already have all the characters of the same. Since there's 26, there's 26 letters, right? So then what we do is we're going to return true. Otherwise, we're going to increase our frequency on our rightmost pointer. Okay. And then if the rightmost is equal to the left most to to the rightmost pointer is equal to the left, the first, the rightmost of the first frequency array, we're going to increase the count. Otherwise, if it's rightmost is like one less than it, right, we're going to decrease the count. And then then we're going to decrease the count of the rightmost character. And then we're what we're going to do is if they're both equal on the left most, then we're going to increase the count. Otherwise, they're not, we're going to decrease the count also, right? If the left side of the rightmost left side of the second strings frequency is equal to the left side of it, minus one, then we're going to decrease the count. And we return if our count is equal to 26, because that would mean that we have the count of frequency match being the same. Okay. I know this is kind of like just going through each of these fast. But as you can see here, it's very, very similar in that except that we're going to have a window shooting to the right. And then we're like decreasing the frequency of the right string, right strings frequency, right and the left strings. Okay. So yeah, it's very similar. Next problem is 1.9 string anagrams given two strings s and p return an array of all star indexes of p anagrams and s, you can return them in any order. The anagram is when one, the number of characters and one is equal to the same number of characters the other. So CBA is an anagram ABC because they have one C, one B, one A, and ABC has one A, one B, one C. So if we look through here, yeah, we start from zero, we see there's a CBA and that's an anagram ABC. So they add the starting index of zero into the array. And then we also see there's a BAC, which is an anagram of ABC. So they added that the starting index, which is of B, which is going to be zero one, two, three, four, five, six. So they added six into your array. Okay. So how do you do this problem? Very easy. Keep track of frequency characters of your of p, right? Second thing, keep keep frequency of that. Have a star pointer and end pointer representing the window length of the window. Our current length, we're going to set equal to just the length of the string p. This difference is going to represent the light if the length of the currently found anagram. So if it equals to the one that we find, then it's found. Okay, loop through our window, get the current character, decrease the decrement the frequency of it. Okay, then if it's greater than equal to zero, we're going to decrease our window, which is the the length of our window of the length, because they want us to find the, yeah, we have to decrease the length of the window. Okay, so we decrease the length of the window. And then after this, after the length of the length of the window zero, yeah, we're going to have like the length of the anagram, right? Okay. So if the difference is equal to zero, we're just going to add the zero index to our solution. Okay, then we're going to loop continue looping through the end of the string, get the current value, the start of the window. If it's greater than equal to zero, we're going to increase our frequency of difference, that means we're further away from the completing anagrams, we have to increment difference. Then we're going to increment the frequency for the current character, going to move our window to the right. And then we're going to get the last character of our window and decrease the frequency of it because that means that we don't need anymore, right? It's because we're decreasing it means it's part of the window now. Again, if it's not negative part of the window, so we're going to decrease our frequency, if it's greater than equal to zero, decrease frequency. If we reach zero, right, if our difference is zero, then we just add the start of our window of the start of the window of our array. And then yeah, then we increase and go to the next iteration. After that we just return solution. Okay, so yeah, that's essentially the gist of this problem. Let's go over another problem, smallest window containing substring, given two strings S and T, where you want to return the minimum window substring of S such that every character in T is inside the window. Okay, we're also including duplicates. So in this case, we have ABC, and then we the smallest window that contains ABC is bank B and C. Okay, so that's the smallest window in S that contains all the characters of ABC. Okay, so how do you do this? Create a frequency dash map, loop through it, increase the frequency of the counter of each character. We're going to have two, two pointers representing the start and then the j is going to represent the right most of the window. We're going to move j to the end. We get the current character. If the frequency array contains the frequency map contains it, we're going to decrease it. And then if it's greater than equal to zero means it's unmatched, we're going to subtract count. So count represents, yeah, count represents the number of characters that you need to match. So currently count is equal to the length of the T, which is like the second string, we need to match. So yeah, we have to subtract count, if our frequency is greater than equal to zero. Okay, because that means like, we're decreasing the number of characters that are remaining remaining. Okay. Alright, so once count is equal to zero, that means that we already found a substring, we're going to move through between our window from i and j. Set flight equals true, we get the length of our window, j minus i plus one. If the current length is less than equal to men, we're going to just set it equal to it. Okay, so yeah, it's less than equal to men, we're going to update our minimum of our left side to equal to i and minimum right side equal to j. And then we're going to get our minimum window is going to equal to the current length, because that's smaller than men. Then we need to shrink the left pointer. So to do that, we get the left character, and then we need to check if it contains it. Then, since we're shrinking it, we're going to increase the frequency count by one. And then if it's greater than equal to one, we increase count plus plus. Okay. Then here, we increment the left pointer, so i plus plus, because we're moving the window downwards. And then j, we're going to move it downwards also afterwards. So yeah, in the end, if our flight is still true, that means that we found a global minimum, we're just going to substring between the minimum left and minimum right, plus one. And then, yeah, then we just return that otherwise, there's no possible way. So we're going to return empty. Okay, so yeah, that's this gist of smallest one, our last problem. And I don't actually understand how this works. But whatever, okay, last problem will go over. You given a string s in an array of string words of the same length, and you need to return the starting indices of all substrings in s that is a concatenation of each word and words. So let's say we have this string s in the words foo bar. So substrings starting with foo and bar. So like bar foo and foo bar would be starting from index zero would be bar foo right here. And then if we want foo bar, it would be this one nine zero one two three five six seven nine foo bar. Okay, so how does this work? I'm not exactly sure. But because just try frequency of strings, okay, we have a frequency of strings, hash map, and we're just going to increment it. Now we're going to have our array of indices. We're going to have the length of our, yeah, a length of our string, length of the number of words, and then just the length of each of the work of each individual words. So we're just going to loop through n minus num, which is the words length, multiply by length of the frequency. So this is just going through, I think every single word in the frequency, I think, not a frequency, every single word in the, it's going through every single word in the array of frequency of words, I think, I believe so. Okay, and then what they're going to do is that they're going to create another hash map sink scene. And they're going to start j is equal to zero. Well, j is less than number. Number is the words length. So it's length of the words. We are just going to substring this do Hickey that I don't know what it's doing, I plus j times length. So it's going to substring each of the words. And then what's going to do is it's going to multiply by a length. Okay, s. And then if it contains it, it increases it. If the scene is greater than the get we break. Otherwise, we break. And we increment j. And if j is equal to number, we add it into our indices and then we return indices. So I actually don't know how this has to do with this. I don't actually know how this works. I'm not sure. But yeah, I don't know. Yeah, sorry, guys, I can't help you on this last problem. But yeah, I hope you guys enjoyed this video. Rick, I'll subscribe. I'll check you guys later. Peace.